[2/4] windowscodecs: Add a stub IWICMetadataReader/Writer implementation.

Vincent Povirk vincent at codeweavers.com
Wed Jan 11 17:23:22 CST 2012


-------------- next part --------------
From 03c997e57981174877a766f598148a5b61befead Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Wed, 11 Jan 2012 16:03:24 -0600
Subject: [PATCH 2/4] windowscodecs: Add a stub IWICMetadataReader/Writer implementation.

---
 dlls/windowscodecs/Makefile.in                |    1 +
 dlls/windowscodecs/clsfactory.c               |    2 +
 dlls/windowscodecs/metadatahandler.c          |  318 +++++++++++++++++++++++++
 dlls/windowscodecs/tests/metadata.c           |    6 +-
 dlls/windowscodecs/wincodecs_private.h        |   23 ++
 dlls/windowscodecs/windowscodecs_wincodec.idl |    7 +
 6 files changed, 354 insertions(+), 3 deletions(-)
 create mode 100644 dlls/windowscodecs/metadatahandler.c

diff --git a/dlls/windowscodecs/Makefile.in b/dlls/windowscodecs/Makefile.in
index 1eeedf6..bcb7a8a 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 105d40a..0f30115 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 0000000..c8341e7
--- /dev/null
+++ b/dlls/windowscodecs/metadatahandler.c
@@ -0,0 +1,318 @@
+/*
+ * 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 <stdarg.h>
+
+#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 e3c3325..06b8e89 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 70abaf9..691b1ec 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 fb4dae6..bf42679 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; }
-- 
1.7.4.1


More information about the wine-patches mailing list