Vincent Povirk : windowscodecs: Implement IWICMetadataWriter::LoadEx.
Alexandre Julliard
julliard at winehq.org
Thu Jan 12 13:19:20 CST 2012
Module: wine
Branch: master
Commit: 60e6653561897238ef22727f5fc7ed618230a410
URL: http://source.winehq.org/git/wine.git/?a=commit;h=60e6653561897238ef22727f5fc7ed618230a410
Author: Vincent Povirk <vincent at codeweavers.com>
Date: Wed Jan 11 16:36:49 2012 -0600
windowscodecs: Implement IWICMetadataWriter::LoadEx.
---
dlls/windowscodecs/metadatahandler.c | 92 ++++++++++++++++++++++++++++++++--
dlls/windowscodecs/tests/metadata.c | 2 +-
2 files changed, 89 insertions(+), 5 deletions(-)
diff --git a/dlls/windowscodecs/metadatahandler.c b/dlls/windowscodecs/metadatahandler.c
index 9dd6cca..0e916f2 100644
--- a/dlls/windowscodecs/metadatahandler.c
+++ b/dlls/windowscodecs/metadatahandler.c
@@ -39,6 +39,9 @@ typedef struct MetadataHandler {
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)
@@ -51,6 +54,20 @@ static inline MetadataHandler *impl_from_IWICPersistStream(IWICPersistStream *if
return CONTAINING_RECORD(iface, MetadataHandler, IWICPersistStream_iface);
}
+static void MetadataHandler_FreeItems(MetadataHandler *This)
+{
+ int 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 WINAPI MetadataHandler_QueryInterface(IWICMetadataWriter *iface, REFIID iid,
void **ppv)
{
@@ -100,6 +117,9 @@ static ULONG WINAPI MetadataHandler_Release(IWICMetadataWriter *iface)
if (ref == 0)
{
+ MetadataHandler_FreeItems(This);
+ This->lock.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection(&This->lock);
HeapFree(GetProcessHeap(), 0, This);
}
@@ -248,8 +268,28 @@ static HRESULT WINAPI MetadataHandler_GetSizeMax(IWICPersistStream *iface,
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;
+ 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,
@@ -290,6 +330,11 @@ HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, IUnknown *pUnkO
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);
@@ -301,8 +346,47 @@ HRESULT MetadataReader_Create(const MetadataHandlerVtbl *vtable, IUnknown *pUnkO
static HRESULT LoadUnknownMetadata(IStream *input, const GUID *preferred_vendor,
DWORD persist_options, MetadataItem **items, DWORD *item_count)
{
- FIXME("\n");
- return E_NOTIMPL;
+ 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 (FAILED(hr))
+ {
+ HeapFree(GetProcessHeap(), 0, data);
+ return hr;
+ }
+
+ result = HeapAlloc(GetProcessHeap(), 0, sizeof(MetadataItem));
+ if (FAILED(hr))
+ {
+ 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.blob.cbSize = bytesread;
+ result[0].value.blob.pBlobData = data;
+
+ *items = result;
+ *item_count = 1;
+
+ return S_OK;
}
static const MetadataHandlerVtbl UnknownMetadataReader_Vtbl = {
diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c
index 06b8e89..43c6f48 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);
- todo_wine ok(hr == S_OK, "LoadEx failed, hr=%x\n", hr);
+ ok(hr == S_OK, "LoadEx failed, hr=%x\n", hr);
IWICPersistStream_Release(persist);
}
More information about the wine-cvs
mailing list