/*
 * Copyright 2012 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>
#include <stdio.h>

#define COBJMACROS
#define NONAMELESSUNION

#include "windef.h"
#include "winbase.h"
#include "winternl.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecsdk.h"

#include "wincodecs_private.h"

#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(wincodecs);

typedef struct MetadataHandler {
    IWICMetadataWriter IWICMetadataWriter_iface;
    LONG ref;
    IWICPersistStream IWICPersistStream_iface;
    const MetadataHandlerVtbl *vtable;
    MetadataItem *items;
    DWORD item_count;
    CRITICAL_SECTION lock;
} MetadataHandler;

static inline MetadataHandler *impl_from_IWICMetadataWriter(IWICMetadataWriter *iface)
{
    return CONTAINING_RECORD(iface, MetadataHandler, IWICMetadataWriter_iface);
}

static inline MetadataHandler *impl_from_IWICPersistStream(IWICPersistStream *iface)
{
    return CONTAINING_RECORD(iface, MetadataHandler, IWICPersistStream_iface);
}

static void MetadataHandler_FreeItems(MetadataHandler *This)
{
    DWORD i;

    for (i=0; i<This->item_count; i++)
    {
        PropVariantClear(&This->items[i].schema);
        PropVariantClear(&This->items[i].id);
        PropVariantClear(&This->items[i].value);
    }

    HeapFree(GetProcessHeap(), 0, This->items);
}

static HRESULT MetadataHandlerEnum_Create(MetadataHandler *parent, DWORD index,
    IWICEnumMetadataItem **ppIEnumMetadataItem);

static HRESULT WINAPI MetadataHandler_QueryInterface(IWICMetadataWriter *iface, REFIID iid,
    void **ppv)
{
    MetadataHandler *This = impl_from_IWICMetadataWriter(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

    if (IsEqualIID(&IID_IUnknown, iid) ||
        IsEqualIID(&IID_IWICMetadataReader, iid) ||
        (IsEqualIID(&IID_IWICMetadataWriter, iid) && This->vtable->is_writer))
    {
        *ppv = &This->IWICMetadataWriter_iface;
    }
    else if (IsEqualIID(&IID_IPersist, iid) ||
             IsEqualIID(&IID_IPersistStream, iid) ||
             IsEqualIID(&IID_IWICPersistStream, iid))
    {
        *ppv = &This->IWICPersistStream_iface;
    }
    else
    {
        *ppv = NULL;
        return E_NOINTERFACE;
    }

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

static ULONG WINAPI MetadataHandler_AddRef(IWICMetadataWriter *iface)
{
    MetadataHandler *This = impl_from_IWICMetadataWriter(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI MetadataHandler_Release(IWICMetadataWriter *iface)
{
    MetadataHandler *This = impl_from_IWICMetadataWriter(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if (ref == 0)
    {
        MetadataHandler_FreeItems(This);
        This->lock.DebugInfo->Spare[0] = 0;
        DeleteCriticalSection(&This->lock);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI MetadataHandler_GetMetadataHandlerInfo(IWICMetadataWriter *iface,
    IWICMetadataHandlerInfo **ppIHandler)
{
    HRESULT hr;
    IWICComponentInfo *component_info;
    MetadataHandler *This = impl_from_IWICMetadataWriter(iface);

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

    hr = CreateComponentInfo(This->vtable->clsid, &component_info);
    if (FAILED(hr)) return hr;

    hr = IWICComponentInfo_QueryInterface(component_info, &IID_IWICMetadataHandlerInfo,
        (void **)ppIHandler);

    IWICComponentInfo_Release(component_info);
    return hr;
}

static HRESULT WINAPI MetadataHandler_GetMetadataFormat(IWICMetadataWriter *iface,
    GUID *pguidMetadataFormat)
{
    HRESULT hr;
    IWICMetadataHandlerInfo *metadata_info;

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

    if (!pguidMetadataFormat) return E_INVALIDARG;

    hr = MetadataHandler_GetMetadataHandlerInfo(iface, &metadata_info);
    if (FAILED(hr)) return hr;

    hr = IWICMetadataHandlerInfo_GetMetadataFormat(metadata_info, pguidMetadataFormat);
    IWICMetadataHandlerInfo_Release(metadata_info);

    return hr;
}

static HRESULT WINAPI MetadataHandler_GetCount(IWICMetadataWriter *iface,
    UINT *pcCount)
{
    MetadataHandler *This = impl_from_IWICMetadataWriter(iface);

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

    if (!pcCount) return E_INVALIDARG;

    *pcCount = This->item_count;
    return S_OK;
}

static HRESULT WINAPI MetadataHandler_GetValueByIndex(IWICMetadataWriter *iface,
    UINT index, PROPVARIANT *schema, PROPVARIANT *id, PROPVARIANT *value)
{
    HRESULT hr = S_OK;
    MetadataHandler *This = impl_from_IWICMetadataWriter(iface);

    TRACE("%p,%u,%p,%p,%p\n", iface, index, schema, id, value);

    EnterCriticalSection(&This->lock);

    if (index >= This->item_count)
    {
        LeaveCriticalSection(&This->lock);
        return E_INVALIDARG;
    }

    if (schema)
        hr = PropVariantCopy(schema, &This->items[index].schema);

    if (SUCCEEDED(hr) && id)
        hr = PropVariantCopy(id, &This->items[index].id);

    if (SUCCEEDED(hr) && value)
        hr = PropVariantCopy(value, &This->items[index].value);

    LeaveCriticalSection(&This->lock);
    return hr;
}

static BOOL get_int_value(const PROPVARIANT *pv, LONGLONG *value)
{
    switch (pv->vt)
    {
    case VT_NULL:
    case VT_EMPTY:
        *value = 0;
        break;
    case VT_I1:
        *value = pv->u.cVal;
        break;
    case VT_UI1:
        *value = pv->u.bVal;
        break;
    case VT_I2:
        *value = pv->u.iVal;
        break;
    case VT_UI2:
        *value = pv->u.uiVal;
        break;
    case VT_I4:
        *value = pv->u.lVal;
        break;
    case VT_UI4:
        *value = pv->u.ulVal;
        break;
    case VT_I8:
    case VT_UI8:
        *value = pv->u.hVal.QuadPart;
        break;
    default:
        FIXME("not supported variant type %d\n", pv->vt);
        return FALSE;
    }
    return TRUE;
}

/* FiXME: Use propsys.PropVariantCompareEx once it's implemented */
static int propvar_cmp(const PROPVARIANT *v1, const PROPVARIANT *v2)
{
    LONGLONG value1, value2;

    if (v1->vt == VT_LPSTR && v2->vt == VT_LPSTR)
    {
        return lstrcmpA(v1->u.pszVal, v2->u.pszVal);
    }

    if (v1->vt == VT_LPWSTR && v2->vt == VT_LPWSTR)
    {
        return lstrcmpiW(v1->u.pwszVal, v2->u.pwszVal);
    }

    if (!get_int_value(v1, &value1)) return -1;
    if (!get_int_value(v2, &value2)) return -1;

    value1 -= value2;
    if (value1) return value1 < 0 ? -1 : 1;
    return 0;
}

static HRESULT WINAPI MetadataHandler_GetValue(IWICMetadataWriter *iface,
    const PROPVARIANT *schema, const PROPVARIANT *id, PROPVARIANT *value)
{
    UINT i;
    HRESULT hr = WINCODEC_ERR_PROPERTYNOTFOUND;
    MetadataHandler *This = impl_from_IWICMetadataWriter(iface);

    TRACE("(%p,%p,%p,%p)\n", iface, schema, id, value);

    if (!id) return E_INVALIDARG;

    EnterCriticalSection(&This->lock);

    for (i = 0; i < This->item_count; i++)
    {
        if (schema && This->items[i].schema.vt != VT_EMPTY)
        {
            if (propvar_cmp(schema, &This->items[i].schema) != 0) continue;
        }

        if (propvar_cmp(id, &This->items[i].id) != 0) continue;

        hr = value ? PropVariantCopy(value, &This->items[i].value) : S_OK;
        break;
    }

    LeaveCriticalSection(&This->lock);
    return hr;
}

static HRESULT WINAPI MetadataHandler_GetEnumerator(IWICMetadataWriter *iface,
    IWICEnumMetadataItem **ppIEnumMetadata)
{
    MetadataHandler *This = impl_from_IWICMetadataWriter(iface);
    TRACE("(%p,%p)\n", iface, ppIEnumMetadata);
    return MetadataHandlerEnum_Create(This, 0, ppIEnumMetadata);
}

static HRESULT WINAPI MetadataHandler_SetValue(IWICMetadataWriter *iface,
    const PROPVARIANT *pvarSchema, const PROPVARIANT *pvarId, const PROPVARIANT *pvarValue)
{
    FIXME("(%p,%p,%p,%p): stub\n", iface, pvarSchema, pvarId, pvarValue);
    return E_NOTIMPL;
}

static HRESULT WINAPI MetadataHandler_SetValueByIndex(IWICMetadataWriter *iface,
    UINT nIndex, const PROPVARIANT *pvarSchema, const PROPVARIANT *pvarId, const PROPVARIANT *pvarValue)
{
    FIXME("(%p,%u,%p,%p,%p): stub\n", iface, nIndex, pvarSchema, pvarId, pvarValue);
    return E_NOTIMPL;
}

static HRESULT WINAPI MetadataHandler_RemoveValue(IWICMetadataWriter *iface,
    const PROPVARIANT *pvarSchema, const PROPVARIANT *pvarId)
{
    FIXME("(%p,%p,%p): stub\n", iface, pvarSchema, pvarId);
    return E_NOTIMPL;
}

static HRESULT WINAPI MetadataHandler_RemoveValueByIndex(IWICMetadataWriter *iface,
    UINT nIndex)
{
    FIXME("(%p,%u): stub\n", iface, nIndex);
    return E_NOTIMPL;
}

static const IWICMetadataWriterVtbl MetadataHandler_Vtbl = {
    MetadataHandler_QueryInterface,
    MetadataHandler_AddRef,
    MetadataHandler_Release,
    MetadataHandler_GetMetadataFormat,
    MetadataHandler_GetMetadataHandlerInfo,
    MetadataHandler_GetCount,
    MetadataHandler_GetValueByIndex,
    MetadataHandler_GetValue,
    MetadataHandler_GetEnumerator,
    MetadataHandler_SetValue,
    MetadataHandler_SetValueByIndex,
    MetadataHandler_RemoveValue,
    MetadataHandler_RemoveValueByIndex
};

static HRESULT WINAPI MetadataHandler_PersistStream_QueryInterface(IWICPersistStream *iface,
    REFIID iid, void **ppv)
{
    MetadataHandler *This = impl_from_IWICPersistStream(iface);
    return IWICMetadataWriter_QueryInterface(&This->IWICMetadataWriter_iface, iid, ppv);
}

static ULONG WINAPI MetadataHandler_PersistStream_AddRef(IWICPersistStream *iface)
{
    MetadataHandler *This = impl_from_IWICPersistStream(iface);
    return IWICMetadataWriter_AddRef(&This->IWICMetadataWriter_iface);
}

static ULONG WINAPI MetadataHandler_PersistStream_Release(IWICPersistStream *iface)
{
    MetadataHandler *This = impl_from_IWICPersistStream(iface);
    return IWICMetadataWriter_Release(&This->IWICMetadataWriter_iface);
}

static HRESULT WINAPI MetadataHandler_GetClassID(IWICPersistStream *iface,
    CLSID *pClassID)
{
    FIXME("(%p,%p): stub\n", iface, pClassID);
    return E_NOTIMPL;
}

static HRESULT WINAPI MetadataHandler_IsDirty(IWICPersistStream *iface)
{
    FIXME("(%p): stub\n", iface);
    return E_NOTIMPL;
}

static HRESULT WINAPI MetadataHandler_Load(IWICPersistStream *iface,
    IStream *pStm)
{
    MetadataHandler *This = impl_from_IWICPersistStream(iface);
    TRACE("(%p,%p)\n", iface, pStm);
    return IWICPersistStream_LoadEx(&This->IWICPersistStream_iface, pStm, NULL, WICPersistOptionsDefault);
}

static HRESULT WINAPI MetadataHandler_Save(IWICPersistStream *iface,
    IStream *pStm, BOOL fClearDirty)
{
    FIXME("(%p,%p,%i): stub\n", iface, pStm, fClearDirty);
    return E_NOTIMPL;
}

static HRESULT WINAPI MetadataHandler_GetSizeMax(IWICPersistStream *iface,
    ULARGE_INTEGER *pcbSize)
{
    FIXME("(%p,%p): stub\n", iface, pcbSize);
    return E_NOTIMPL;
}

static HRESULT WINAPI MetadataHandler_LoadEx(IWICPersistStream *iface,
    IStream *pIStream, const GUID *pguidPreferredVendor, DWORD dwPersistOptions)
{
    MetadataHandler *This = impl_from_IWICPersistStream(iface);
    HRESULT hr;
    MetadataItem *new_items=NULL;
    DWORD item_count=0;

    TRACE("(%p,%p,%s,%x)\n", iface, pIStream, debugstr_guid(pguidPreferredVendor), dwPersistOptions);

    EnterCriticalSection(&This->lock);

    hr = This->vtable->fnLoad(pIStream, pguidPreferredVendor, dwPersistOptions,
        &new_items, &item_count);

    if (SUCCEEDED(hr))
    {
        MetadataHandler_FreeItems(This);
        This->items = new_items;
        This->item_count = item_count;
    }

    LeaveCriticalSection(&This->lock);

    return hr;
}

static HRESULT WINAPI MetadataHandler_SaveEx(IWICPersistStream *iface,
    IStream *pIStream, DWORD dwPersistOptions, BOOL fClearDirty)
{
    FIXME("(%p,%p,%x,%i): stub\n", iface, pIStream, dwPersistOptions, fClearDirty);
    return E_NOTIMPL;
}

static const IWICPersistStreamVtbl MetadataHandler_PersistStream_Vtbl = {
    MetadataHandler_PersistStream_QueryInterface,
    MetadataHandler_PersistStream_AddRef,
    MetadataHandler_PersistStream_Release,
    MetadataHandler_GetClassID,
    MetadataHandler_IsDirty,
    MetadataHandler_Load,
    MetadataHandler_Save,
    MetadataHandler_GetSizeMax,
    MetadataHandler_LoadEx,
    MetadataHandler_SaveEx
};

HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
    MetadataHandler *This;
    HRESULT hr;

    TRACE("%s\n", debugstr_guid(vtable->clsid));

    *ppv = NULL;

    if (pUnkOuter) return CLASS_E_NOAGGREGATION;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataHandler));
    if (!This) return E_OUTOFMEMORY;

    This->IWICMetadataWriter_iface.lpVtbl = &MetadataHandler_Vtbl;
    This->IWICPersistStream_iface.lpVtbl = &MetadataHandler_PersistStream_Vtbl;
    This->ref = 1;
    This->vtable = vtable;
    This->items = NULL;
    This->item_count = 0;

    InitializeCriticalSection(&This->lock);
    This->lock.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": MetadataHandler.lock");

    hr = IWICMetadataWriter_QueryInterface(&This->IWICMetadataWriter_iface, iid, ppv);

    IWICMetadataWriter_Release(&This->IWICMetadataWriter_iface);

    return hr;
}

typedef struct MetadataHandlerEnum {
    IWICEnumMetadataItem IWICEnumMetadataItem_iface;
    LONG ref;
    MetadataHandler *parent;
    DWORD index;
} MetadataHandlerEnum;

static inline MetadataHandlerEnum *impl_from_IWICEnumMetadataItem(IWICEnumMetadataItem *iface)
{
    return CONTAINING_RECORD(iface, MetadataHandlerEnum, IWICEnumMetadataItem_iface);
}

static HRESULT WINAPI MetadataHandlerEnum_QueryInterface(IWICEnumMetadataItem *iface, REFIID iid,
    void **ppv)
{
    MetadataHandlerEnum *This = impl_from_IWICEnumMetadataItem(iface);
    TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv);

    if (!ppv) return E_INVALIDARG;

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

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

static ULONG WINAPI MetadataHandlerEnum_AddRef(IWICEnumMetadataItem *iface)
{
    MetadataHandlerEnum *This = impl_from_IWICEnumMetadataItem(iface);
    ULONG ref = InterlockedIncrement(&This->ref);

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

    return ref;
}

static ULONG WINAPI MetadataHandlerEnum_Release(IWICEnumMetadataItem *iface)
{
    MetadataHandlerEnum *This = impl_from_IWICEnumMetadataItem(iface);
    ULONG ref = InterlockedDecrement(&This->ref);

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

    if (ref == 0)
    {
        IWICMetadataWriter_Release(&This->parent->IWICMetadataWriter_iface);
        HeapFree(GetProcessHeap(), 0, This);
    }

    return ref;
}

static HRESULT WINAPI MetadataHandlerEnum_Next(IWICEnumMetadataItem *iface,
    ULONG celt, PROPVARIANT *rgeltSchema, PROPVARIANT *rgeltId,
    PROPVARIANT *rgeltValue, ULONG *pceltFetched)
{
    MetadataHandlerEnum *This = impl_from_IWICEnumMetadataItem(iface);
    ULONG new_index;
    HRESULT hr=S_FALSE;
    ULONG i;

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

    EnterCriticalSection(&This->parent->lock);

    if (This->index >= This->parent->item_count)
    {
        *pceltFetched = 0;
        LeaveCriticalSection(&This->parent->lock);
        return S_FALSE;
    }

    new_index = min(This->parent->item_count, This->index + celt);
    *pceltFetched = new_index - This->index;

    if (rgeltSchema)
    {
        for (i=0; SUCCEEDED(hr) && i < *pceltFetched; i++)
            hr = PropVariantCopy(&rgeltSchema[i], &This->parent->items[i+This->index].schema);
    }

    for (i=0; SUCCEEDED(hr) && i < *pceltFetched; i++)
        hr = PropVariantCopy(&rgeltId[i], &This->parent->items[i+This->index].id);

    if (rgeltValue)
    {
        for (i=0; SUCCEEDED(hr) && i < *pceltFetched; i++)
            hr = PropVariantCopy(&rgeltValue[i], &This->parent->items[i+This->index].value);
    }

    if (SUCCEEDED(hr))
    {
        This->index = new_index;
    }

    LeaveCriticalSection(&This->parent->lock);

    return hr;
}

static HRESULT WINAPI MetadataHandlerEnum_Skip(IWICEnumMetadataItem *iface,
    ULONG celt)
{
    MetadataHandlerEnum *This = impl_from_IWICEnumMetadataItem(iface);

    EnterCriticalSection(&This->parent->lock);

    This->index += celt;

    LeaveCriticalSection(&This->parent->lock);

    return S_OK;
}

static HRESULT WINAPI MetadataHandlerEnum_Reset(IWICEnumMetadataItem *iface)
{
    MetadataHandlerEnum *This = impl_from_IWICEnumMetadataItem(iface);

    EnterCriticalSection(&This->parent->lock);

    This->index = 0;

    LeaveCriticalSection(&This->parent->lock);

    return S_OK;
}

static HRESULT WINAPI MetadataHandlerEnum_Clone(IWICEnumMetadataItem *iface,
    IWICEnumMetadataItem **ppIEnumMetadataItem)
{
    MetadataHandlerEnum *This = impl_from_IWICEnumMetadataItem(iface);
    HRESULT hr;

    EnterCriticalSection(&This->parent->lock);

    hr = MetadataHandlerEnum_Create(This->parent, This->index, ppIEnumMetadataItem);

    LeaveCriticalSection(&This->parent->lock);

    return hr;
}

static const IWICEnumMetadataItemVtbl MetadataHandlerEnum_Vtbl = {
    MetadataHandlerEnum_QueryInterface,
    MetadataHandlerEnum_AddRef,
    MetadataHandlerEnum_Release,
    MetadataHandlerEnum_Next,
    MetadataHandlerEnum_Skip,
    MetadataHandlerEnum_Reset,
    MetadataHandlerEnum_Clone
};

static HRESULT MetadataHandlerEnum_Create(MetadataHandler *parent, DWORD index,
    IWICEnumMetadataItem **ppIEnumMetadataItem)
{
    MetadataHandlerEnum *This;

    if (!ppIEnumMetadataItem) return E_INVALIDARG;

    *ppIEnumMetadataItem = NULL;

    This = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataHandlerEnum));
    if (!This) return E_OUTOFMEMORY;

    IWICMetadataWriter_AddRef(&parent->IWICMetadataWriter_iface);

    This->IWICEnumMetadataItem_iface.lpVtbl = &MetadataHandlerEnum_Vtbl;
    This->ref = 1;
    This->parent = parent;
    This->index = index;

    *ppIEnumMetadataItem = &This->IWICEnumMetadataItem_iface;

    return S_OK;
}

static HRESULT LoadUnknownMetadata(IStream *input, const GUID *preferred_vendor,
    DWORD persist_options, MetadataItem **items, DWORD *item_count)
{
    HRESULT hr;
    MetadataItem *result;
    STATSTG stat;
    BYTE *data;
    ULONG bytesread;

    TRACE("\n");

    hr = IStream_Stat(input, &stat, STATFLAG_NONAME);
    if (FAILED(hr))
        return hr;

    data = HeapAlloc(GetProcessHeap(), 0, stat.cbSize.QuadPart);
    if (!data) return E_OUTOFMEMORY;

    hr = IStream_Read(input, data, stat.cbSize.QuadPart, &bytesread);
    if (bytesread != stat.cbSize.QuadPart) hr = E_FAIL;
    if (hr != S_OK)
    {
        HeapFree(GetProcessHeap(), 0, data);
        return hr;
    }

    result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem));
    if (!result)
    {
        HeapFree(GetProcessHeap(), 0, data);
        return E_OUTOFMEMORY;
    }

    PropVariantInit(&result[0].schema);
    PropVariantInit(&result[0].id);
    PropVariantInit(&result[0].value);

    result[0].value.vt = VT_BLOB;
    result[0].value.u.blob.cbSize = bytesread;
    result[0].value.u.blob.pBlobData = data;

    *items = result;
    *item_count = 1;

    return S_OK;
}

static const MetadataHandlerVtbl UnknownMetadataReader_Vtbl = {
    0,
    &CLSID_WICUnknownMetadataReader,
    LoadUnknownMetadata
};

HRESULT UnknownMetadataReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv)
{
    return MetadataReader_Create(&UnknownMetadataReader_Vtbl, pUnkOuter, iid, ppv);
}

#define SWAP_USHORT(x) do { if (!native_byte_order) (x) = RtlUshortByteSwap(x); } while(0)
#define SWAP_ULONG(x) do { if (!native_byte_order) (x) = RtlUlongByteSwap(x); } while(0)
#define SWAP_ULONGLONG(x) do { if (!native_byte_order) (x) = RtlUlonglongByteSwap(x); } while(0)

struct IFD_entry
{
    SHORT id;
    SHORT type;
    ULONG count;
    LONG  value;
};

#define IFD_BYTE 1
#define IFD_ASCII 2
#define IFD_SHORT 3
#define IFD_LONG 4
#define IFD_RATIONAL 5
#define IFD_SBYTE 6
#define IFD_UNDEFINED 7
#define IFD_SSHORT 8
#define IFD_SLONG 9
#define IFD_SRATIONAL 10
#define IFD_FLOAT 11
#define IFD_DOUBLE 12
#define IFD_IFD 13

static int tag_to_vt(SHORT tag)
{
    static const int tag2vt[] =
    {
        VT_EMPTY, /* 0 */
        VT_UI1,   /* IFD_BYTE 1 */
        VT_LPSTR, /* IFD_ASCII 2 */
        VT_UI2,   /* IFD_SHORT 3 */
        VT_UI4,   /* IFD_LONG 4 */
        VT_UI8,   /* IFD_RATIONAL 5 */
        VT_I1,    /* IFD_SBYTE 6 */
        VT_BLOB,  /* IFD_UNDEFINED 7 */
        VT_I2,    /* IFD_SSHORT 8 */
        VT_I4,    /* IFD_SLONG 9 */
        VT_I8,    /* IFD_SRATIONAL 10 */
        VT_R4,    /* IFD_FLOAT 11 */
        VT_R8,    /* IFD_DOUBLE 12 */
        VT_BLOB,  /* IFD_IFD 13 */
    };
    return (tag > 0 && tag <= 13) ? tag2vt[tag] : VT_BLOB;
}

static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
                              MetadataItem *item, BOOL native_byte_order)
{
    ULONG count, value, i, bytesread;
    SHORT type;
    LARGE_INTEGER pos;
    HRESULT hr;

    item->schema.vt = VT_EMPTY;
    item->id.vt = VT_UI2;
    item->id.u.uiVal = entry->id;
    SWAP_USHORT(item->id.u.uiVal);

    count = entry->count;
    SWAP_ULONG(count);
    type = entry->type;
    SWAP_USHORT(type);
    item->value.vt = tag_to_vt(type);
    value = entry->value;
    SWAP_ULONG(value);

    switch (type)
    {
     case IFD_BYTE:
     case IFD_SBYTE:
        if (!count) count = 1;

        if (count <= 4)
        {
            const BYTE *data = (const BYTE *)&entry->value;

            if (count == 1)
                item->value.u.bVal = data[0];
            else
            {
                item->value.vt |= VT_VECTOR;
                item->value.u.caub.cElems = count;
                item->value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, count);
                memcpy(item->value.u.caub.pElems, data, count);
            }
            break;
        }

        item->value.vt |= VT_VECTOR;
        item->value.u.caub.cElems = count;
        item->value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, count);
        if (!item->value.u.caub.pElems) return E_OUTOFMEMORY;

        pos.QuadPart = value;
        hr = IStream_Seek(input, pos, SEEK_SET, NULL);
        if (FAILED(hr))
        {
            HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems);
            return hr;
        }
        hr = IStream_Read(input, item->value.u.caub.pElems, count, &bytesread);
        if (bytesread != count) hr = E_FAIL;
        if (hr != S_OK)
        {
            HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems);
            return hr;
        }
        break;
    case IFD_SHORT:
    case IFD_SSHORT:
        if (!count) count = 1;

        if (count <= 2)
        {
            const SHORT *data = (const SHORT *)&entry->value;

            if (count == 1)
            {
                item->value.u.uiVal = data[0];
                SWAP_USHORT(item->value.u.uiVal);
            }
            else
            {
                item->value.vt |= VT_VECTOR;
                item->value.u.caui.cElems = count;
                item->value.u.caui.pElems = HeapAlloc(GetProcessHeap(), 0, count * 2);
                memcpy(item->value.u.caui.pElems, data, count * 2);
                for (i = 0; i < count; i++)
                    SWAP_USHORT(item->value.u.caui.pElems[i]);
            }
            break;
        }

        item->value.vt |= VT_VECTOR;
        item->value.u.caui.cElems = count;
        item->value.u.caui.pElems = HeapAlloc(GetProcessHeap(), 0, count * 2);
        if (!item->value.u.caui.pElems) return E_OUTOFMEMORY;

        pos.QuadPart = value;
        hr = IStream_Seek(input, pos, SEEK_SET, NULL);
        if (FAILED(hr))
        {
            HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems);
            return hr;
        }
        hr = IStream_Read(input, item->value.u.caui.pElems, count * 2, &bytesread);
        if (bytesread != count * 2) hr = E_FAIL;
        if (hr != S_OK)
        {
            HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems);
            return hr;
        }
        for (i = 0; i < count; i++)
            SWAP_USHORT(item->value.u.caui.pElems[i]);
        break;
    case IFD_LONG:
    case IFD_SLONG:
    case IFD_FLOAT:
        if (!count) count = 1;

        if (count == 1)
        {
            item->value.u.ulVal = value;
            break;
        }

        item->value.vt |= VT_VECTOR;
        item->value.u.caul.cElems = count;
        item->value.u.caul.pElems = HeapAlloc(GetProcessHeap(), 0, count * 4);
        if (!item->value.u.caul.pElems) return E_OUTOFMEMORY;

        pos.QuadPart = value;
        hr = IStream_Seek(input, pos, SEEK_SET, NULL);
        if (FAILED(hr))
        {
            HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems);
            return hr;
        }
        hr = IStream_Read(input, item->value.u.caul.pElems, count * 4, &bytesread);
        if (bytesread != count * 4) hr = E_FAIL;
        if (hr != S_OK)
        {
            HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems);
            return hr;
        }
        for (i = 0; i < count; i++)
            SWAP_ULONG(item->value.u.caul.pElems[i]);
        break;
    case IFD_RATIONAL:
    case IFD_SRATIONAL:
    case IFD_DOUBLE:
        if (!count)
        {
            FIXME("IFD field type %d, count 0\n", type);
            item->value.vt = VT_EMPTY;
            break;
        }

        if (count == 1)
        {
            ULONGLONG ull;

            pos.QuadPart = value;
            hr = IStream_Seek(input, pos, SEEK_SET, NULL);
            if (FAILED(hr)) return hr;

            hr = IStream_Read(input, &ull, sizeof(ull), &bytesread);
            if (bytesread != sizeof(ull)) hr = E_FAIL;
            if (hr != S_OK) return hr;

            item->value.u.uhVal.QuadPart = ull;

            if (type == IFD_DOUBLE)
                SWAP_ULONGLONG(item->value.u.uhVal.QuadPart);
            else
            {
                SWAP_ULONG(item->value.u.uhVal.u.LowPart);
                SWAP_ULONG(item->value.u.uhVal.u.HighPart);
            }
            break;
        }
        else
        {
            item->value.vt |= VT_VECTOR;
            item->value.u.cauh.cElems = count;
            item->value.u.cauh.pElems = HeapAlloc(GetProcessHeap(), 0, count * 8);
            if (!item->value.u.cauh.pElems) return E_OUTOFMEMORY;

            pos.QuadPart = value;
            hr = IStream_Seek(input, pos, SEEK_SET, NULL);
            if (FAILED(hr))
            {
                HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems);
                return hr;
            }
            hr = IStream_Read(input, item->value.u.cauh.pElems, count * 8, &bytesread);
            if (bytesread != count * 8) hr = E_FAIL;
            if (hr != S_OK)
            {
                HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems);
                return hr;
            }
            for (i = 0; i < count; i++)
            {
                if (type == IFD_DOUBLE)
                    SWAP_ULONGLONG(item->value.u.cauh.pElems[i].QuadPart);
                else
                {
                    SWAP_ULONG(item->value.u.cauh.pElems[i].u.LowPart);
                    SWAP_ULONG(item->value.u.cauh.pElems[i].u.HighPart);
                }
            }
        }
        break;
    case IFD_ASCII:
        item->value.u.pszVal = HeapAlloc(GetProcessHeap(), 0, count + 1);
        if (!item->value.u.pszVal) return E_OUTOFMEMORY;

        if (count <= 4)
        {
            const char *data = (const char *)&entry->value;
            memcpy(item->value.u.pszVal, data, count);
            item->value.u.pszVal[count] = 0;
            break;
        }

        pos.QuadPart = value;
        hr = IStream_Seek(input, pos, SEEK_SET, NULL);
        if (FAILED(hr))
        {
            HeapFree(GetProcessHeap(), 0, item->value.u.pszVal);
            return hr;
        }
        hr = IStream_Read(input, item->value.u.pszVal, count, &bytesread);
        if (bytesread != count) hr = E_FAIL;
        if (hr != S_OK)
        {
            HeapFree(GetProcessHeap(), 0, item->value.u.pszVal);
            return hr;
        }
        item->value.u.pszVal[count] = 0;
        break;
    case IFD_UNDEFINED:
        if (!count)
        {
            FIXME("IFD field type %d, count 0\n", type);
            item->value.vt = VT_EMPTY;
            break;
        }

        item->value.u.blob.pBlobData = HeapAlloc(GetProcessHeap(), 0, count);
        if (!item->value.u.blob.pBlobData) return E_OUTOFMEMORY;

        item->value.u.blob.cbSize = count;

        if (count <= 4)
        {
            const char *data = (const char *)&entry->value;
            memcpy(item->value.u.blob.pBlobData, data, count);
            break;
        }

        pos.QuadPart = value;
        hr = IStream_Seek(input, pos, SEEK_SET, NULL);
        if (FAILED(hr))
        {
            HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData);
            return hr;
        }
        hr = IStream_Read(input, item->value.u.blob.pBlobData, count, &bytesread);
        if (bytesread != count) hr = E_FAIL;
        if (hr != S_OK)
        {
            HeapFree(GetProcessHeap(), 0, item->value.u.blob.pBlobData);
            return hr;
        }
        break;
    default:
        FIXME("loading field of type %d, count %u is not implemented\n", type, count);
        break;
    }
    return S_OK;
}

static HRESULT LoadIfdMetadata(IStream *input, const GUID *preferred_vendor,
    DWORD persist_options, MetadataItem **items, DWORD *item_count)
{
    HRESULT hr;
    MetadataItem *result;
    USHORT count, i;
    struct IFD_entry *entry;
    BOOL native_byte_order = TRUE;
    ULONG bytesread;

    TRACE("\n");

#ifdef WORDS_BIGENDIAN
    if (persist_options & WICPersistOptionsLittleEndian)
#else
    if (persist_options & WICPersistOptionsBigEndian)
#endif
        native_byte_order = FALSE;

    hr = IStream_Read(input, &count, sizeof(count), &bytesread);
    if (bytesread != sizeof(count)) hr = E_FAIL;
    if (hr != S_OK) return hr;

    SWAP_USHORT(count);

    entry = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*entry));
    if (!entry) return E_OUTOFMEMORY;

    hr = IStream_Read(input, entry, count * sizeof(*entry), &bytesread);
    if (bytesread != count * sizeof(*entry)) hr = E_FAIL;
    if (hr != S_OK)
    {
        HeapFree(GetProcessHeap(), 0, entry);
        return hr;
    }

    /* limit number of IFDs to 4096 to avoid infinite loop */
    for (i = 0; i < 4096; i++)
    {
        ULONG next_ifd_offset;
        LARGE_INTEGER pos;
        USHORT next_ifd_count;

        hr = IStream_Read(input, &next_ifd_offset, sizeof(next_ifd_offset), &bytesread);
        if (bytesread != sizeof(next_ifd_offset)) hr = E_FAIL;
        if (hr != S_OK) break;

        SWAP_ULONG(next_ifd_offset);
        if (!next_ifd_offset) break;

        pos.QuadPart = next_ifd_offset;
        hr = IStream_Seek(input, pos, SEEK_SET, NULL);
        if (FAILED(hr)) break;

        hr = IStream_Read(input, &next_ifd_count, sizeof(next_ifd_count), &bytesread);
        if (bytesread != sizeof(next_ifd_count)) hr = E_FAIL;
        if (hr != S_OK) break;

        SWAP_USHORT(next_ifd_count);

        pos.QuadPart = next_ifd_count * sizeof(*entry);
        hr = IStream_Seek(input, pos, SEEK_CUR, NULL);
        if (FAILED(hr)) break;
    }

    if (hr != S_OK || i == 4096)
    {
        HeapFree(GetProcessHeap(), 0, entry);
        return WINCODEC_ERR_BADMETADATAHEADER;
    }

    result = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*result));
    if (!result)
    {
        HeapFree(GetProcessHeap(), 0, entry);
        return E_OUTOFMEMORY;
    }

    for (i = 0; i < count; i++)
    {
        hr = load_IFD_entry(input, &entry[i], &result[i], native_byte_order);
        if (FAILED(hr))
        {
            HeapFree(GetProcessHeap(), 0, entry);
            HeapFree(GetProcessHeap(), 0, result);
            return hr;
        }
    }

    HeapFree(GetProcessHeap(), 0, entry);

    *items = result;
    *item_count = count;

    return S_OK;
}

static const MetadataHandlerVtbl IfdMetadataReader_Vtbl = {
    0,
    &CLSID_WICIfdMetadataReader,
    LoadIfdMetadata
};

HRESULT IfdMetadataReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void **ppv)
{
    return MetadataReader_Create(&IfdMetadataReader_Vtbl, pUnkOuter, iid, ppv);
}
