Module: wine Branch: master Commit: ec43788803648ad689274cb44be5c9434d5f7322 URL: http://source.winehq.org/git/wine.git/?a=commit;h=ec43788803648ad689274cb44b...
Author: Dmitry Timoshkov dmitry@baikal.ru Date: Wed Jun 13 18:30:54 2012 +0900
windowscodecs: Implement partial loading of IFD metadata.
---
dlls/windowscodecs/metadatahandler.c | 127 +++++++++++++++++++++++++++++++++- dlls/windowscodecs/tests/metadata.c | 1 - 2 files changed, 124 insertions(+), 4 deletions(-)
diff --git a/dlls/windowscodecs/metadatahandler.c b/dlls/windowscodecs/metadatahandler.c index a4dc174..20785b4 100644 --- a/dlls/windowscodecs/metadatahandler.c +++ b/dlls/windowscodecs/metadatahandler.c @@ -19,6 +19,7 @@ #include "config.h"
#include <stdarg.h> +#include <stdio.h>
#define COBJMACROS #define NONAMELESSUNION @@ -598,13 +599,133 @@ HRESULT UnknownMetadataReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, vo return MetadataReader_Create(&UnknownMetadataReader_Vtbl, pUnkOuter, iid, ppv); }
+#include "pshpack2.h" +struct IFD_entry +{ + SHORT id; + SHORT type; + ULONG length; + LONG value; +}; + +struct IFD_rational +{ + LONG numerator; + LONG denominator; +}; +#include "poppack.h" + +#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 HRESULT load_IFD_entry(IStream *input, struct IFD_entry *entry, MetadataItem *item) +{ + item->schema.vt = VT_EMPTY; + item->id.vt = VT_UI2; + item->id.u.uiVal = entry->id; + + switch (entry->type) + { + case IFD_SHORT: + if (entry->length == 1) + { + item->value.vt = VT_UI2; + item->value.u.uiVal = entry->value; + break; + } + FIXME("loading multiple short fields is not implemented\n"); + break; + case IFD_LONG: + if (entry->length == 1) + { + item->value.vt = VT_UI4; + item->value.u.ulVal = entry->value; + break; + } + FIXME("loading multiple long fields is not implemented\n"); + break; + case IFD_RATIONAL: + if (entry->length == 1) + { + HRESULT hr; + LARGE_INTEGER pos; + struct IFD_rational rational; + + pos.QuadPart = entry->value; + hr = IStream_Seek(input, pos, SEEK_SET, NULL); + if (FAILED(hr)) return hr; + + item->value.vt = VT_UI8; + hr = IStream_Read(input, &rational , sizeof(rational), NULL); + if (FAILED(hr)) return hr; + item->value.u.uhVal.QuadPart = ((LONGLONG)rational.denominator << 32) | rational.numerator; + break; + } + FIXME("loading multiple rational fields is not implemented\n"); + break; + default: + FIXME("loading field of type %d is not implemented\n", entry->type); + break; + } + return S_OK; +} + static HRESULT LoadIfdMetadata(IStream *input, const GUID *preferred_vendor, DWORD persist_options, MetadataItem **items, DWORD *item_count) { - FIXME("stub\n"); + HRESULT hr; + MetadataItem *result; + USHORT count, i; + struct IFD_entry *entry; + + TRACE("\n"); + + hr = IStream_Read(input, &count, sizeof(count), NULL); + if (FAILED(hr)) return hr; + + entry = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*entry)); + if (!entry) return E_OUTOFMEMORY;
- *items = NULL; - *item_count = 0; + hr = IStream_Read(input, entry, count * sizeof(*entry), NULL); + if (FAILED(hr)) + { + HeapFree(GetProcessHeap(), 0, entry); + return hr; + } + + 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]); + 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; } diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c index 6b25963..cf00f1f 100644 --- a/dlls/windowscodecs/tests/metadata.c +++ b/dlls/windowscodecs/tests/metadata.c @@ -386,7 +386,6 @@ static void test_metadata_IFD(void)
hr = IWICMetadataReader_GetCount(reader, &count); ok(hr == S_OK, "GetCount error %#x\n", hr); -todo_wine ok(count == 6, "unexpected count %u\n", count);
hr = IWICMetadataReader_GetEnumerator(reader, NULL);