/*
 * Copyright 2009 Vincent Povirk for CodeWeavers
 * Copyright 2012 Dmitry Timoshkov
 *
 * 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 "wincodecs_private.h"

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

WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);

static const WCHAR mimetypes_valuename[] = {'M','i','m','e','T','y','p','e','s',0};
static const WCHAR author_valuename[] = {'A','u','t','h','o','r',0};
static const WCHAR friendlyname_valuename[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
static const WCHAR pixelformats_keyname[] = {'P','i','x','e','l','F','o','r','m','a','t','s',0};
static const WCHAR formats_keyname[] = {'F','o','r','m','a','t','s',0};
static const WCHAR containerformat_valuename[] = {'C','o','n','t','a','i','n','e','r','F','o','r','m','a','t',0};
static const WCHAR metadataformat_valuename[] = {'M','e','t','a','d','a','t','a','F','o','r','m','a','t',0};
static const WCHAR vendor_valuename[] = {'V','e','n','d','o','r',0};
static const WCHAR version_valuename[] = {'V','e','r','s','i','o','n',0};
static const WCHAR specversion_valuename[] = {'S','p','e','c','V','e','r','s','i','o','n',0};
static const WCHAR bitsperpixel_valuename[] = {'B','i','t','L','e','n','g','t','h',0};
static const WCHAR channelcount_valuename[] = {'C','h','a','n','n','e','l','C','o','u','n','t',0};
static const WCHAR channelmasks_keyname[] = {'C','h','a','n','n','e','l','M','a','s','k','s',0};
static const WCHAR numericrepresentation_valuename[] = {'N','u','m','e','r','i','c','R','e','p','r','e','s','e','n','t','a','t','i','o','n',0};
static const WCHAR supportstransparency_valuename[] = {'S','u','p','p','o','r','t','s','T','r','a','n','s','p','a','r','e','n','c','y',0};
static const WCHAR requiresfullstream_valuename[] = {'R','e','q','u','i','r','e','s','F','u','l','l','S','t','r','e','a','m',0};
static const WCHAR supportspadding_valuename[] = {'S','u','p','p','o','r','t','s','P','a','d','d','i','n','g',0};
static const WCHAR fileextensions_valuename[] = {'F','i','l','e','E','x','t','e','n','s','i','o','n','s',0};
static const WCHAR containers_keyname[] = {'C','o','n','t','a','i','n','e','r','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 == ERROR_FILE_NOT_FOUND)
    {
        *actual_size = 0;
        return S_OK;
    }

    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);
}

static HRESULT ComponentInfo_GetGUIDValue(HKEY classkey, LPCWSTR value,
    GUID *result)
{
    LONG ret;
    WCHAR guid_string[39];
    DWORD cbdata = sizeof(guid_string);
    HRESULT hr;

    if (!result)
        return E_INVALIDARG;

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

    if (ret != ERROR_SUCCESS)
        return HRESULT_FROM_WIN32(ret);

    if (cbdata < sizeof(guid_string))
    {
        ERR("incomplete GUID value\n");
        return E_FAIL;
    }

    hr = CLSIDFromString(guid_string, result);

    return hr;
}

static HRESULT ComponentInfo_GetDWORDValue(HKEY classkey, LPCWSTR value,
    DWORD *result)
{
    LONG ret;
    DWORD cbdata = sizeof(DWORD);

    if (!result)
        return E_INVALIDARG;

    ret = RegGetValueW(classkey, NULL, value, RRF_RT_DWORD, NULL,
        result, &cbdata);

    if (ret == ERROR_FILE_NOT_FOUND)
    {
        *result = 0;
        return S_OK;
    }

    return HRESULT_FROM_WIN32(ret);
}

static HRESULT ComponentInfo_GetGuidList(HKEY classkey, LPCWSTR subkeyname,
    UINT buffersize, GUID *buffer, UINT *actual_size)
{
    LONG ret;
    HKEY subkey;
    UINT items_returned;
    WCHAR guid_string[39];
    DWORD guid_string_size;
    HRESULT hr=S_OK;

    if (!actual_size)
        return E_INVALIDARG;

    ret = RegOpenKeyExW(classkey, subkeyname, 0, KEY_READ, &subkey);
    if (ret == ERROR_FILE_NOT_FOUND)
    {
        *actual_size = 0;
        return S_OK;
    }
    else if (ret != ERROR_SUCCESS) return HRESULT_FROM_WIN32(ret);

    if (buffer)
    {
        items_returned = 0;
        guid_string_size = 39;
        while (items_returned < buffersize)
        {
            ret = RegEnumKeyExW(subkey, items_returned, guid_string,
                &guid_string_size, NULL, NULL, NULL, NULL);

            if (ret != ERROR_SUCCESS)
            {
                hr = HRESULT_FROM_WIN32(ret);
                break;
            }

            if (guid_string_size != 38)
            {
                hr = E_FAIL;
                break;
            }

            hr = CLSIDFromString(guid_string, &buffer[items_returned]);
            if (FAILED(hr))
                break;

            items_returned++;
            guid_string_size = 39;
        }

        if (ret == ERROR_NO_MORE_ITEMS)
            hr = S_OK;

        *actual_size = items_returned;
    }
    else
    {
        ret = RegQueryInfoKeyW(subkey, NULL, NULL, NULL, actual_size, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
        if (ret != ERROR_SUCCESS)
            hr = HRESULT_FROM_WIN32(ret);
    }

    RegCloseKey(subkey);

    return hr;
}

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->IWICBitmapDecoderInfo_iface;
    }
    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);
    if (!pType) return E_INVALIDARG;
    *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)
{
    BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, author_valuename,
        cchAuthor, wzAuthor, pcchActual);
}

static HRESULT WINAPI BitmapDecoderInfo_GetVendorGUID(IWICBitmapDecoderInfo *iface, GUID *pguidVendor)
{
    BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);

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

    return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
}

static HRESULT WINAPI BitmapDecoderInfo_GetVersion(IWICBitmapDecoderInfo *iface, UINT cchVersion,
    WCHAR *wzVersion, UINT *pcchActual)
{
    BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, version_valuename,
        cchVersion, wzVersion, pcchActual);
}

static HRESULT WINAPI BitmapDecoderInfo_GetSpecVersion(IWICBitmapDecoderInfo *iface, UINT cchSpecVersion,
    WCHAR *wzSpecVersion, UINT *pcchActual)
{
    BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
        cchSpecVersion, wzSpecVersion, pcchActual);
}

static HRESULT WINAPI BitmapDecoderInfo_GetFriendlyName(IWICBitmapDecoderInfo *iface, UINT cchFriendlyName,
    WCHAR *wzFriendlyName, UINT *pcchActual)
{
    BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
        cchFriendlyName, wzFriendlyName, pcchActual);
}

static HRESULT WINAPI BitmapDecoderInfo_GetContainerFormat(IWICBitmapDecoderInfo *iface,
    GUID *pguidContainerFormat)
{
    BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
    TRACE("(%p,%p)\n", iface, pguidContainerFormat);
    return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
}

static HRESULT WINAPI BitmapDecoderInfo_GetPixelFormats(IWICBitmapDecoderInfo *iface,
    UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
{
    BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);
    TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual);
    return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual);
}

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)
{
    BitmapDecoderInfo *This = impl_from_IWICBitmapDecoderInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchFileExtensions, wzFileExtensions, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, fileextensions_valuename,
        cchFileExtensions, wzFileExtensions, pcchActual);
}

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;
    UINT i;
    ULONG 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 create_instance(&This->clsid, &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->IWICBitmapDecoderInfo_iface;
    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->IWICBitmapEncoderInfo_iface;
    }
    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);
    if (!pType) return E_INVALIDARG;
    *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)
{
    BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, author_valuename,
        cchAuthor, wzAuthor, pcchActual);
}

static HRESULT WINAPI BitmapEncoderInfo_GetVendorGUID(IWICBitmapEncoderInfo *iface, GUID *pguidVendor)
{
    BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);

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

    return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
}

static HRESULT WINAPI BitmapEncoderInfo_GetVersion(IWICBitmapEncoderInfo *iface, UINT cchVersion,
    WCHAR *wzVersion, UINT *pcchActual)
{
    BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, version_valuename,
        cchVersion, wzVersion, pcchActual);
}

static HRESULT WINAPI BitmapEncoderInfo_GetSpecVersion(IWICBitmapEncoderInfo *iface, UINT cchSpecVersion,
    WCHAR *wzSpecVersion, UINT *pcchActual)
{
    BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
        cchSpecVersion, wzSpecVersion, pcchActual);
}

static HRESULT WINAPI BitmapEncoderInfo_GetFriendlyName(IWICBitmapEncoderInfo *iface, UINT cchFriendlyName,
    WCHAR *wzFriendlyName, UINT *pcchActual)
{
    BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
        cchFriendlyName, wzFriendlyName, pcchActual);
}

static HRESULT WINAPI BitmapEncoderInfo_GetContainerFormat(IWICBitmapEncoderInfo *iface,
    GUID *pguidContainerFormat)
{
    BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
    TRACE("(%p,%p)\n", iface, pguidContainerFormat);
    return ComponentInfo_GetGUIDValue(This->classkey, containerformat_valuename, pguidContainerFormat);
}

static HRESULT WINAPI BitmapEncoderInfo_GetPixelFormats(IWICBitmapEncoderInfo *iface,
    UINT cFormats, GUID *pguidPixelFormats, UINT *pcActual)
{
    BitmapEncoderInfo *This = impl_from_IWICBitmapEncoderInfo(iface);
    TRACE("(%p,%u,%p,%p)\n", iface, cFormats, pguidPixelFormats, pcActual);
    return ComponentInfo_GetGuidList(This->classkey, formats_keyname, cFormats, pguidPixelFormats, pcActual);
}

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 create_instance(&This->clsid, &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->IWICBitmapEncoderInfo_iface;
    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->IWICFormatConverterInfo_iface;
    }
    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);
    if (!pType) return E_INVALIDARG;
    *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)
{
    FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, author_valuename,
        cchAuthor, wzAuthor, pcchActual);
}

static HRESULT WINAPI FormatConverterInfo_GetVendorGUID(IWICFormatConverterInfo *iface, GUID *pguidVendor)
{
    FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);

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

    return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
}

static HRESULT WINAPI FormatConverterInfo_GetVersion(IWICFormatConverterInfo *iface, UINT cchVersion,
    WCHAR *wzVersion, UINT *pcchActual)
{
    FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, version_valuename,
        cchVersion, wzVersion, pcchActual);
}

static HRESULT WINAPI FormatConverterInfo_GetSpecVersion(IWICFormatConverterInfo *iface, UINT cchSpecVersion,
    WCHAR *wzSpecVersion, UINT *pcchActual)
{
    FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
        cchSpecVersion, wzSpecVersion, pcchActual);
}

static HRESULT WINAPI FormatConverterInfo_GetFriendlyName(IWICFormatConverterInfo *iface, UINT cchFriendlyName,
    WCHAR *wzFriendlyName, UINT *pcchActual)
{
    FormatConverterInfo *This = impl_from_IWICFormatConverterInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
        cchFriendlyName, wzFriendlyName, pcchActual);
}

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 create_instance(&This->clsid, &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->IWICFormatConverterInfo_iface;
    return S_OK;
}

typedef struct {
    IWICPixelFormatInfo2 IWICPixelFormatInfo2_iface;
    LONG ref;
    HKEY classkey;
    CLSID clsid;
} PixelFormatInfo;

static inline PixelFormatInfo *impl_from_IWICPixelFormatInfo2(IWICPixelFormatInfo2 *iface)
{
    return CONTAINING_RECORD(iface, PixelFormatInfo, IWICPixelFormatInfo2_iface);
}

static HRESULT WINAPI PixelFormatInfo_QueryInterface(IWICPixelFormatInfo2 *iface, REFIID iid,
    void **ppv)
{
    PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(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_IWICPixelFormatInfo, iid) ||
        IsEqualIID(&IID_IWICPixelFormatInfo2 ,iid))
    {
        *ppv = &This->IWICPixelFormatInfo2_iface;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }

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

static ULONG WINAPI PixelFormatInfo_AddRef(IWICPixelFormatInfo2 *iface)
{
    PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI PixelFormatInfo_Release(IWICPixelFormatInfo2 *iface)
{
    PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(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 PixelFormatInfo_GetComponentType(IWICPixelFormatInfo2 *iface,
    WICComponentType *pType)
{
    TRACE("(%p,%p)\n", iface, pType);
    if (!pType) return E_INVALIDARG;
    *pType = WICPixelFormat;
    return S_OK;
}

static HRESULT WINAPI PixelFormatInfo_GetCLSID(IWICPixelFormatInfo2 *iface, CLSID *pclsid)
{
    PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
    TRACE("(%p,%p)\n", iface, pclsid);

    if (!pclsid)
        return E_INVALIDARG;

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

    return S_OK;
}

static HRESULT WINAPI PixelFormatInfo_GetSigningStatus(IWICPixelFormatInfo2 *iface, DWORD *pStatus)
{
    TRACE("(%p,%p)\n", iface, pStatus);

    if (!pStatus)
        return E_INVALIDARG;

    /* Pixel formats don't require code, so they are considered signed. */
    *pStatus = WICComponentSigned;

    return S_OK;
}

static HRESULT WINAPI PixelFormatInfo_GetAuthor(IWICPixelFormatInfo2 *iface, UINT cchAuthor,
    WCHAR *wzAuthor, UINT *pcchActual)
{
    PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchAuthor, wzAuthor, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, author_valuename,
        cchAuthor, wzAuthor, pcchActual);
}

static HRESULT WINAPI PixelFormatInfo_GetVendorGUID(IWICPixelFormatInfo2 *iface, GUID *pguidVendor)
{
    PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);

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

    return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, pguidVendor);
}

static HRESULT WINAPI PixelFormatInfo_GetVersion(IWICPixelFormatInfo2 *iface, UINT cchVersion,
    WCHAR *wzVersion, UINT *pcchActual)
{
    PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchVersion, wzVersion, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, version_valuename,
        cchVersion, wzVersion, pcchActual);
}

static HRESULT WINAPI PixelFormatInfo_GetSpecVersion(IWICPixelFormatInfo2 *iface, UINT cchSpecVersion,
    WCHAR *wzSpecVersion, UINT *pcchActual)
{
    PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchSpecVersion, wzSpecVersion, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
        cchSpecVersion, wzSpecVersion, pcchActual);
}

static HRESULT WINAPI PixelFormatInfo_GetFriendlyName(IWICPixelFormatInfo2 *iface, UINT cchFriendlyName,
    WCHAR *wzFriendlyName, UINT *pcchActual)
{
    PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, cchFriendlyName, wzFriendlyName, pcchActual);

    return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
        cchFriendlyName, wzFriendlyName, pcchActual);
}

static HRESULT WINAPI PixelFormatInfo_GetFormatGUID(IWICPixelFormatInfo2 *iface,
    GUID *pFormat)
{
    PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
    TRACE("(%p,%p)\n", iface, pFormat);

    if (!pFormat)
        return E_INVALIDARG;

    *pFormat = This->clsid;

    return S_OK;
}

static HRESULT WINAPI PixelFormatInfo_GetColorContext(IWICPixelFormatInfo2 *iface,
    IWICColorContext **ppIColorContext)
{
    FIXME("(%p,%p): stub\n", iface, ppIColorContext);
    return E_NOTIMPL;
}

static HRESULT WINAPI PixelFormatInfo_GetBitsPerPixel(IWICPixelFormatInfo2 *iface,
    UINT *puiBitsPerPixel)
{
    PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);

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

    return ComponentInfo_GetDWORDValue(This->classkey, bitsperpixel_valuename, puiBitsPerPixel);
}

static HRESULT WINAPI PixelFormatInfo_GetChannelCount(IWICPixelFormatInfo2 *iface,
    UINT *puiChannelCount)
{
    PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);

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

    return ComponentInfo_GetDWORDValue(This->classkey, channelcount_valuename, puiChannelCount);
}

static HRESULT WINAPI PixelFormatInfo_GetChannelMask(IWICPixelFormatInfo2 *iface,
    UINT uiChannelIndex, UINT cbMaskBuffer, BYTE *pbMaskBuffer, UINT *pcbActual)
{
    static const WCHAR uintformatW[] = {'%','u',0};
    PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);
    UINT channel_count;
    HRESULT hr;
    LONG ret;
    WCHAR valuename[11];
    DWORD cbData;

    TRACE("(%p,%u,%u,%p,%p)\n", iface, uiChannelIndex, cbMaskBuffer, pbMaskBuffer, pcbActual);

    if (!pcbActual)
        return E_INVALIDARG;

    hr = PixelFormatInfo_GetChannelCount(iface, &channel_count);

    if (SUCCEEDED(hr) && uiChannelIndex >= channel_count)
        hr = E_INVALIDARG;

    if (SUCCEEDED(hr))
    {
        snprintfW(valuename, 11, uintformatW, uiChannelIndex);

        cbData = cbMaskBuffer;

        ret = RegGetValueW(This->classkey, channelmasks_keyname, valuename, RRF_RT_REG_BINARY, NULL, pbMaskBuffer, &cbData);

        if (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA)
            *pcbActual = cbData;

        if (ret == ERROR_MORE_DATA)
            hr = E_INVALIDARG;
        else
            hr = HRESULT_FROM_WIN32(ret);
    }

    return hr;
}

static HRESULT WINAPI PixelFormatInfo_SupportsTransparency(IWICPixelFormatInfo2 *iface,
    BOOL *pfSupportsTransparency)
{
    PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);

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

    return ComponentInfo_GetDWORDValue(This->classkey, supportstransparency_valuename, (DWORD*)pfSupportsTransparency);
}

static HRESULT WINAPI PixelFormatInfo_GetNumericRepresentation(IWICPixelFormatInfo2 *iface,
    WICPixelFormatNumericRepresentation *pNumericRepresentation)
{
    PixelFormatInfo *This = impl_from_IWICPixelFormatInfo2(iface);

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

    return ComponentInfo_GetDWORDValue(This->classkey, numericrepresentation_valuename, pNumericRepresentation);
}

static const IWICPixelFormatInfo2Vtbl PixelFormatInfo_Vtbl = {
    PixelFormatInfo_QueryInterface,
    PixelFormatInfo_AddRef,
    PixelFormatInfo_Release,
    PixelFormatInfo_GetComponentType,
    PixelFormatInfo_GetCLSID,
    PixelFormatInfo_GetSigningStatus,
    PixelFormatInfo_GetAuthor,
    PixelFormatInfo_GetVendorGUID,
    PixelFormatInfo_GetVersion,
    PixelFormatInfo_GetSpecVersion,
    PixelFormatInfo_GetFriendlyName,
    PixelFormatInfo_GetFormatGUID,
    PixelFormatInfo_GetColorContext,
    PixelFormatInfo_GetBitsPerPixel,
    PixelFormatInfo_GetChannelCount,
    PixelFormatInfo_GetChannelMask,
    PixelFormatInfo_SupportsTransparency,
    PixelFormatInfo_GetNumericRepresentation
};

static HRESULT PixelFormatInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **ppIInfo)
{
    PixelFormatInfo *This;

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

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

    *ppIInfo = (IWICComponentInfo *)&This->IWICPixelFormatInfo2_iface;
    return S_OK;
}

typedef struct
{
    IWICMetadataReaderInfo IWICMetadataReaderInfo_iface;
    LONG ref;
    HKEY classkey;
    CLSID clsid;
} MetadataReaderInfo;

static inline MetadataReaderInfo *impl_from_IWICMetadataReaderInfo(IWICMetadataReaderInfo *iface)
{
    return CONTAINING_RECORD(iface, MetadataReaderInfo, IWICMetadataReaderInfo_iface);
}

static HRESULT WINAPI MetadataReaderInfo_QueryInterface(IWICMetadataReaderInfo *iface,
    REFIID riid, void **ppv)
{
    MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);

    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(riid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, riid) ||
        IsEqualIID(&IID_IWICComponentInfo, riid) ||
        IsEqualIID(&IID_IWICMetadataHandlerInfo, riid) ||
        IsEqualIID(&IID_IWICMetadataReaderInfo, riid))
    {
        *ppv = &This->IWICMetadataReaderInfo_iface;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }

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

static ULONG WINAPI MetadataReaderInfo_AddRef(IWICMetadataReaderInfo *iface)
{
    MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

static ULONG WINAPI MetadataReaderInfo_Release(IWICMetadataReaderInfo *iface)
{
    MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

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

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

static HRESULT WINAPI MetadataReaderInfo_GetComponentType(IWICMetadataReaderInfo *iface,
    WICComponentType *type)
{
    TRACE("(%p,%p)\n", iface, type);

    if (!type) return E_INVALIDARG;
    *type = WICMetadataReader;
    return S_OK;
}

static HRESULT WINAPI MetadataReaderInfo_GetCLSID(IWICMetadataReaderInfo *iface,
    CLSID *clsid)
{
    MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);

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

    if (!clsid) return E_INVALIDARG;
    *clsid = This->clsid;
    return S_OK;
}

static HRESULT WINAPI MetadataReaderInfo_GetSigningStatus(IWICMetadataReaderInfo *iface,
    DWORD *status)
{
    FIXME("(%p,%p): stub\n", iface, status);
    return E_NOTIMPL;
}

static HRESULT WINAPI MetadataReaderInfo_GetAuthor(IWICMetadataReaderInfo *iface,
    UINT length, WCHAR *author, UINT *actual_length)
{
    MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, length, author, actual_length);

    return ComponentInfo_GetStringValue(This->classkey, author_valuename,
                                        length, author, actual_length);
}

static HRESULT WINAPI MetadataReaderInfo_GetVendorGUID(IWICMetadataReaderInfo *iface,
    GUID *vendor)
{
    MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);

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

    return ComponentInfo_GetGUIDValue(This->classkey, vendor_valuename, vendor);
}

static HRESULT WINAPI MetadataReaderInfo_GetVersion(IWICMetadataReaderInfo *iface,
    UINT length, WCHAR *version, UINT *actual_length)
{
    MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length);

    return ComponentInfo_GetStringValue(This->classkey, version_valuename,
                                        length, version, actual_length);
}

static HRESULT WINAPI MetadataReaderInfo_GetSpecVersion(IWICMetadataReaderInfo *iface,
    UINT length, WCHAR *version, UINT *actual_length)
{
    MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, length, version, actual_length);

    return ComponentInfo_GetStringValue(This->classkey, specversion_valuename,
                                        length, version, actual_length);
}

static HRESULT WINAPI MetadataReaderInfo_GetFriendlyName(IWICMetadataReaderInfo *iface,
    UINT length, WCHAR *name, UINT *actual_length)
{
    MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);

    TRACE("(%p,%u,%p,%p)\n", iface, length, name, actual_length);

    return ComponentInfo_GetStringValue(This->classkey, friendlyname_valuename,
                                        length, name, actual_length);
}

static HRESULT WINAPI MetadataReaderInfo_GetMetadataFormat(IWICMetadataReaderInfo *iface,
    GUID *format)
{
    MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
    TRACE("(%p,%p)\n", iface, format);
    return ComponentInfo_GetGUIDValue(This->classkey, metadataformat_valuename, format);
}

static HRESULT WINAPI MetadataReaderInfo_GetContainerFormats(IWICMetadataReaderInfo *iface,
    UINT length, GUID *formats, UINT *actual_length)
{
    MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
    TRACE("(%p,%u,%p,%p)\n", iface, length, formats, actual_length);

    return ComponentInfo_GetGuidList(This->classkey, containers_keyname, length,
        formats, actual_length);
}

static HRESULT WINAPI MetadataReaderInfo_GetDeviceManufacturer(IWICMetadataReaderInfo *iface,
    UINT length, WCHAR *manufacturer, UINT *actual_length)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, length, manufacturer, actual_length);
    return E_NOTIMPL;
}

static HRESULT WINAPI MetadataReaderInfo_GetDeviceModels(IWICMetadataReaderInfo *iface,
    UINT length, WCHAR *models, UINT *actual_length)
{
    FIXME("(%p,%u,%p,%p): stub\n", iface, length, models, actual_length);
    return E_NOTIMPL;
}

static HRESULT WINAPI MetadataReaderInfo_DoesRequireFullStream(IWICMetadataReaderInfo *iface,
    BOOL *param)
{
    MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
    TRACE("(%p,%p)\n", iface, param);
    return ComponentInfo_GetDWORDValue(This->classkey, requiresfullstream_valuename, (DWORD *)param);
}

static HRESULT WINAPI MetadataReaderInfo_DoesSupportPadding(IWICMetadataReaderInfo *iface,
    BOOL *param)
{
    MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
    TRACE("(%p,%p)\n", iface, param);
    return ComponentInfo_GetDWORDValue(This->classkey, supportspadding_valuename, (DWORD *)param);
}

static HRESULT WINAPI MetadataReaderInfo_DoesRequireFixedSize(IWICMetadataReaderInfo *iface,
    BOOL *param)
{
    FIXME("(%p,%p): stub\n", iface, param);
    return E_NOTIMPL;
}

static HRESULT WINAPI MetadataReaderInfo_GetPatterns(IWICMetadataReaderInfo *iface,
    REFGUID container, UINT length, WICMetadataPattern *patterns, UINT *count, UINT *actual_length)
{
    MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);
    HRESULT hr=S_OK;
    LONG res;
    UINT pattern_count=0, patterns_size=0;
    DWORD valuesize, patternsize;
    BYTE *bPatterns=(BYTE*)patterns;
    HKEY containers_key, guid_key, pattern_key;
    WCHAR subkeyname[11];
    WCHAR guidkeyname[39];
    int i;
    static const WCHAR uintformatW[] = {'%','u',0};
    static const WCHAR patternW[] = {'P','a','t','t','e','r','n',0};
    static const WCHAR positionW[] = {'P','o','s','i','t','i','o','n',0};
    static const WCHAR maskW[] = {'M','a','s','k',0};
    static const WCHAR dataoffsetW[] = {'D','a','t','a','O','f','f','s','e','t',0};

    TRACE("(%p,%s,%u,%p,%p,%p)\n", iface, debugstr_guid(container), length, patterns, count, actual_length);

    if (!actual_length || !container) return E_INVALIDARG;

    res = RegOpenKeyExW(This->classkey, containers_keyname, 0, KEY_READ, &containers_key);
    if (res == ERROR_SUCCESS)
    {
        StringFromGUID2(container, guidkeyname, 39);

        res = RegOpenKeyExW(containers_key, guidkeyname, 0, KEY_READ, &guid_key);
        if (res == ERROR_FILE_NOT_FOUND) hr = WINCODEC_ERR_COMPONENTNOTFOUND;
        else if (res != ERROR_SUCCESS) hr = HRESULT_FROM_WIN32(res);

        RegCloseKey(containers_key);
    }
    else if (res == ERROR_FILE_NOT_FOUND) hr = WINCODEC_ERR_COMPONENTNOTFOUND;
    else hr = HRESULT_FROM_WIN32(res);

    if (SUCCEEDED(hr))
    {
        res = RegQueryInfoKeyW(guid_key, NULL, NULL, NULL, &pattern_count, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
        if (res != ERROR_SUCCESS) hr = HRESULT_FROM_WIN32(res);

        if (SUCCEEDED(hr))
        {
            patterns_size = pattern_count * sizeof(WICMetadataPattern);

            for (i=0; i<pattern_count; i++)
            {
                snprintfW(subkeyname, 11, uintformatW, i);
                res = RegOpenKeyExW(guid_key, subkeyname, 0, KEY_READ, &pattern_key);
                if (res == ERROR_SUCCESS)
                {
                    res = RegGetValueW(pattern_key, NULL, patternW, RRF_RT_REG_BINARY, NULL,
                        NULL, &patternsize);
                    patterns_size += patternsize*2;

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

                        patterns[i].DataOffset.QuadPart = 0;
                        valuesize = sizeof(ULARGE_INTEGER);
                        RegGetValueW(pattern_key, NULL, dataoffsetW, RRF_RT_DWORD|RRF_RT_QWORD, NULL,
                            &patterns[i].DataOffset, &valuesize);

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

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

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

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

        RegCloseKey(guid_key);
    }

    if (hr == S_OK)
    {
        *count = pattern_count;
        *actual_length = patterns_size;
        if (patterns && length < patterns_size)
            hr = WINCODEC_ERR_INSUFFICIENTBUFFER;
    }

    return hr;
}

static HRESULT WINAPI MetadataReaderInfo_MatchesPattern(IWICMetadataReaderInfo *iface,
    REFGUID container, IStream *stream, BOOL *matches)
{
    HRESULT hr;
    WICMetadataPattern *patterns;
    UINT pattern_count=0, patterns_size=0;
    ULONG datasize=0;
    BYTE *data=NULL;
    ULONG bytesread;
    UINT i;
    LARGE_INTEGER seekpos;
    ULONG pos;

    TRACE("(%p,%s,%p,%p)\n", iface, debugstr_guid(container), stream, matches);

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

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

    hr = MetadataReaderInfo_GetPatterns(iface, container, 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;
            }
        }

        seekpos.QuadPart = patterns[i].Position.QuadPart;
        hr = IStream_Seek(stream, seekpos, STREAM_SEEK_SET, NULL);
        if (FAILED(hr)) break;

        hr = IStream_Read(stream, 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;
            *matches = TRUE;
            break;
        }
    }

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

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

    return hr;
}

static HRESULT WINAPI MetadataReaderInfo_CreateInstance(IWICMetadataReaderInfo *iface,
    IWICMetadataReader **reader)
{
    MetadataReaderInfo *This = impl_from_IWICMetadataReaderInfo(iface);

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

    return create_instance(&This->clsid, &IID_IWICMetadataReader, (void **)reader);
}

static const IWICMetadataReaderInfoVtbl MetadataReaderInfo_Vtbl = {
    MetadataReaderInfo_QueryInterface,
    MetadataReaderInfo_AddRef,
    MetadataReaderInfo_Release,
    MetadataReaderInfo_GetComponentType,
    MetadataReaderInfo_GetCLSID,
    MetadataReaderInfo_GetSigningStatus,
    MetadataReaderInfo_GetAuthor,
    MetadataReaderInfo_GetVendorGUID,
    MetadataReaderInfo_GetVersion,
    MetadataReaderInfo_GetSpecVersion,
    MetadataReaderInfo_GetFriendlyName,
    MetadataReaderInfo_GetMetadataFormat,
    MetadataReaderInfo_GetContainerFormats,
    MetadataReaderInfo_GetDeviceManufacturer,
    MetadataReaderInfo_GetDeviceModels,
    MetadataReaderInfo_DoesRequireFullStream,
    MetadataReaderInfo_DoesSupportPadding,
    MetadataReaderInfo_DoesRequireFixedSize,
    MetadataReaderInfo_GetPatterns,
    MetadataReaderInfo_MatchesPattern,
    MetadataReaderInfo_CreateInstance
};

static HRESULT MetadataReaderInfo_Constructor(HKEY classkey, REFCLSID clsid, IWICComponentInfo **info)
{
    MetadataReaderInfo *This;

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

    This->IWICMetadataReaderInfo_iface.lpVtbl = &MetadataReaderInfo_Vtbl;
    This->ref = 1;
    This->classkey = classkey;
    This->clsid = *clsid;

    *info = (IWICComponentInfo *)&This->IWICMetadataReaderInfo_iface;
    return S_OK;
}

static const WCHAR clsid_keyname[] = {'C','L','S','I','D',0};
static const WCHAR 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},
    {WICPixelFormat, &CATID_WICPixelFormats, PixelFormatInfo_Constructor},
    {WICMetadataReader, &CATID_WICMetadataReader, MetadataReaderInfo_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;
    BOOL found = FALSE;
    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 = TRUE;
                }
                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
    {
        FIXME("%s is not supported\n", wine_dbgstr_guid(clsid));
        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->IEnumUnknown_iface;
    }
    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);
    ULONG 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);
    ULONG 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))
    {
        IEnumUnknown_Release(&new_enum->IEnumUnknown_iface);
        *ppenum = NULL;
    }
    else
        *ppenum = &new_enum->IEnumUnknown_iface;

    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(&This->IEnumUnknown_iface);
        *ppIEnumUnknown = &This->IEnumUnknown_iface;
    }
    else
    {
        *ppIEnumUnknown = NULL;
        IEnumUnknown_Release(&This->IEnumUnknown_iface);
    }

    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)
    {
        res = IWICFormatConverter_QueryInterface(converter, &IID_IWICBitmapSource, (void **)ppIDst);
        IWICFormatConverter_Release(converter);
        return res;
    }
    else
    {
        FIXME("cannot convert %s to %s\n", debugstr_guid(&srcFormat), debugstr_guid(dstFormat));
        *ppIDst = NULL;
        return WINCODEC_ERR_COMPONENTNOTFOUND;
    }
}
