From 6b2d1ce1300a1392f602fbf2d3c7f50a86c9efcd Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Wed, 11 Jan 2012 16:03:24 -0600 Subject: [PATCH] windowscodecs: Add a stub IWICMetadataReader/Writer implementation. --- dlls/windowscodecs/Makefile.in | 1 + dlls/windowscodecs/clsfactory.c | 2 + dlls/windowscodecs/metadatahandler.c | 317 ++++++++++++++++++++++++++ dlls/windowscodecs/tests/metadata.c | 6 +- dlls/windowscodecs/wincodecs_private.h | 23 ++ dlls/windowscodecs/windowscodecs_wincodec.idl | 7 + 6 files changed, 353 insertions(+), 3 deletions(-) create mode 100644 dlls/windowscodecs/metadatahandler.c diff --git a/dlls/windowscodecs/Makefile.in b/dlls/windowscodecs/Makefile.in index 1eeedf6ae45..bcb7a8a3588 100644 --- a/dlls/windowscodecs/Makefile.in +++ b/dlls/windowscodecs/Makefile.in @@ -18,6 +18,7 @@ C_SRCS = \ info.c \ jpegformat.c \ main.c \ + metadatahandler.c \ palette.c \ pngformat.c \ propertybag.c \ diff --git a/dlls/windowscodecs/clsfactory.c b/dlls/windowscodecs/clsfactory.c index 105d40ad11c..0f30115ebca 100644 --- a/dlls/windowscodecs/clsfactory.c +++ b/dlls/windowscodecs/clsfactory.c @@ -29,6 +29,7 @@ #include "ocidl.h" #include "initguid.h" #include "wincodec.h" +#include "wincodecsdk.h" #include "wincodecs_private.h" @@ -57,6 +58,7 @@ static classinfo wic_classes[] = { {&CLSID_WICIcnsEncoder, IcnsEncoder_CreateInstance}, {&CLSID_WICDefaultFormatConverter, FormatConverter_CreateInstance}, {&CLSID_WineTgaDecoder, TgaDecoder_CreateInstance}, + {&CLSID_WICUnknownMetadataReader, UnknownMetadataReader_CreateInstance}, {0}}; typedef struct { diff --git a/dlls/windowscodecs/metadatahandler.c b/dlls/windowscodecs/metadatahandler.c new file mode 100644 index 00000000000..9dd6cca74b4 --- /dev/null +++ b/dlls/windowscodecs/metadatahandler.c @@ -0,0 +1,317 @@ +/* + * Copyright 2012 Vincent Povirk for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include "config.h" + +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.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; +} 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 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) + { + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static HRESULT WINAPI MetadataHandler_GetMetadataFormat(IWICMetadataWriter *iface, + GUID *pguidMetadataFormat) +{ + FIXME("(%p,%s): stub\n", iface, debugstr_guid(pguidMetadataFormat)); + return E_NOTIMPL; +} + +static HRESULT WINAPI MetadataHandler_GetMetadataHandlerInfo(IWICMetadataWriter *iface, + IWICMetadataHandlerInfo **ppIHandler) +{ + FIXME("(%p,%p): stub\n", iface, ppIHandler); + return E_NOTIMPL; +} + +static HRESULT WINAPI MetadataHandler_GetCount(IWICMetadataWriter *iface, + UINT *pcCount) +{ + FIXME("(%p,%p): stub\n", iface, pcCount); + return E_NOTIMPL; +} + +static HRESULT WINAPI MetadataHandler_GetValueByIndex(IWICMetadataWriter *iface, + UINT nIndex, PROPVARIANT *pvarSchema, PROPVARIANT *pvarId, PROPVARIANT *pvarValue) +{ + FIXME("(%p,%u,%p,%p,%p): stub\n", iface, nIndex, pvarSchema, pvarId, pvarValue); + return E_NOTIMPL; +} + +static HRESULT WINAPI MetadataHandler_GetValue(IWICMetadataWriter *iface, + const PROPVARIANT *pvarSchema, const PROPVARIANT *pvarId, PROPVARIANT *pvarValue) +{ + FIXME("(%p,%p,%p,%p): stub\n", iface, pvarSchema, pvarId, pvarValue); + return E_NOTIMPL; +} + +static HRESULT WINAPI MetadataHandler_GetEnumerator(IWICMetadataWriter *iface, + IWICEnumMetadataItem **ppIEnumMetadata) +{ + FIXME("(%p,%p): stub\n", iface, ppIEnumMetadata); + return E_NOTIMPL; +} + +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) +{ + FIXME("(%p,%p): stub\n", iface, pStm); + return E_NOTIMPL; +} + +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) +{ + FIXME("(%p,%p,%s,%x): stub\n", iface, pIStream, debugstr_guid(pguidPreferredVendor), dwPersistOptions); + return E_NOTIMPL; +} + +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; + + hr = IWICMetadataWriter_QueryInterface(&This->IWICMetadataWriter_iface, iid, ppv); + + IWICMetadataWriter_Release(&This->IWICMetadataWriter_iface); + + return hr; +} + +static HRESULT LoadUnknownMetadata(IStream *input, const GUID *preferred_vendor, + DWORD persist_options, MetadataItem **items, DWORD *item_count) +{ + FIXME("\n"); + return E_NOTIMPL; +} + +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); +} diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c index e3c33250c04..06b8e898a93 100644 --- a/dlls/windowscodecs/tests/metadata.c +++ b/dlls/windowscodecs/tests/metadata.c @@ -100,7 +100,7 @@ static void load_stream(IUnknown *reader, const char *data, int data_size) if (SUCCEEDED(hr)) { hr = IWICPersistStream_LoadEx(persist, stream, NULL, WICPersistOptionsDefault); - ok(hr == S_OK, "LoadEx failed, hr=%x\n", hr); + todo_wine ok(hr == S_OK, "LoadEx failed, hr=%x\n", hr); IWICPersistStream_Release(persist); } @@ -118,13 +118,13 @@ static void test_metadata_unknown(void) hr = CoCreateInstance(&CLSID_WICUnknownMetadataReader, NULL, CLSCTX_INPROC_SERVER, &IID_IWICMetadataReader, (void**)&reader); - todo_wine ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); + ok(hr == S_OK, "CoCreateInstance failed, hr=%x\n", hr); if (FAILED(hr)) return; load_stream((IUnknown*)reader, metadata_unknown, sizeof(metadata_unknown)); hr = IWICMetadataReader_GetEnumerator(reader, &enumerator); - ok(hr == S_OK, "GetEnumerator failed, hr=%x\n", hr); + todo_wine ok(hr == S_OK, "GetEnumerator failed, hr=%x\n", hr); if (SUCCEEDED(hr)) { diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h index 70abaf93160..691b1ec5d7e 100644 --- a/dlls/windowscodecs/wincodecs_private.h +++ b/dlls/windowscodecs/wincodecs_private.h @@ -64,4 +64,27 @@ extern HRESULT IcoDibDecoder_CreateInstance(BmpDecoder **ppDecoder) DECLSPEC_HID extern void BmpDecoder_GetWICDecoder(BmpDecoder *This, IWICBitmapDecoder **ppDecoder) DECLSPEC_HIDDEN; extern void BmpDecoder_FindIconMask(BmpDecoder *This, ULONG *mask_offset, int *topdown) DECLSPEC_HIDDEN; +typedef struct _MetadataItem +{ + PROPVARIANT schema; + PROPVARIANT id; + PROPVARIANT value; +} MetadataItem; + +typedef struct _MetadataHandlerVtbl +{ + int is_writer; + const CLSID *clsid; + HRESULT (*fnLoad)(IStream *stream, const GUID *preferred_vendor, + DWORD persist_options, MetadataItem **items, DWORD *item_count); + HRESULT (*fnSave)(IStream *stream, DWORD persist_options, + const MetadataItem *items, DWORD item_count); + HRESULT (*fnGetSizeMax)(const MetadataItem *items, DWORD item_count, + ULARGE_INTEGER *size); +} MetadataHandlerVtbl; + +extern HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN; + +extern HRESULT UnknownMetadataReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) DECLSPEC_HIDDEN; + #endif /* WINCODECS_PRIVATE_H */ diff --git a/dlls/windowscodecs/windowscodecs_wincodec.idl b/dlls/windowscodecs/windowscodecs_wincodec.idl index fb4dae61681..bf426796897 100644 --- a/dlls/windowscodecs/windowscodecs_wincodec.idl +++ b/dlls/windowscodecs/windowscodecs_wincodec.idl @@ -114,3 +114,10 @@ coclass WICDefaultFormatConverter { interface IWICFormatConverter; } uuid(b11fc79a-67cc-43e6-a9ce-e3d54945d304) ] coclass WineTgaDecoder { interface IWICBitmapDecoder; } + +[ + helpstring("WIC Unknown Metadata Reader"), + threading(both), + uuid(699745c2-5066-4b82-a8e3-d40478dbec8c) +] +coclass WICUnknownMetadataReader { interface IWICMetadataReader; } -- 2.11.4.GIT