[03/11] windowscodecs: Add support for WICPersistOptionsLittleEndian/WICPersistOptionsBigEndian in the IFD metadata reader. Resend.
Dmitry Timoshkov
dmitry at baikal.ru
Wed Jun 13 04:31:02 CDT 2012
---
dlls/windowscodecs/metadatahandler.c | 51 ++++++++++++++++++++++++++--------
1 file changed, 40 insertions(+), 11 deletions(-)
diff --git a/dlls/windowscodecs/metadatahandler.c b/dlls/windowscodecs/metadatahandler.c
index 20785b4..d2eb8b3 100644
--- a/dlls/windowscodecs/metadatahandler.c
+++ b/dlls/windowscodecs/metadatahandler.c
@@ -1,5 +1,6 @@
/*
* 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
@@ -26,6 +27,7 @@
#include "windef.h"
#include "winbase.h"
+#include "winternl.h"
#include "objbase.h"
#include "wincodec.h"
#include "wincodecsdk.h"
@@ -599,12 +601,16 @@ HRESULT UnknownMetadataReader_CreateInstance(IUnknown *pUnkOuter, REFIID iid, vo
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)
+
#include "pshpack2.h"
struct IFD_entry
{
SHORT id;
SHORT type;
- ULONG length;
+ ULONG count;
LONG value;
};
@@ -629,47 +635,60 @@ struct IFD_rational
#define IFD_DOUBLE 12
#define IFD_IFD 13
-static HRESULT load_IFD_entry(IStream *input, struct IFD_entry *entry, MetadataItem *item)
+static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
+ MetadataItem *item, BOOL native_byte_order)
{
+ ULONG count, value;
+ SHORT type;
+
item->schema.vt = VT_EMPTY;
item->id.vt = VT_UI2;
item->id.u.uiVal = entry->id;
+ SWAP_USHORT(item->id.u.uiVal);
- switch (entry->type)
+ count = entry->count;
+ SWAP_ULONG(count);
+ type = entry->type;
+ SWAP_USHORT(type);
+ value = entry->value;
+ SWAP_ULONG(value);
+
+ switch (type)
{
case IFD_SHORT:
- if (entry->length == 1)
+ if (count == 1)
{
item->value.vt = VT_UI2;
- item->value.u.uiVal = entry->value;
+ item->value.u.uiVal = value;
break;
}
FIXME("loading multiple short fields is not implemented\n");
break;
case IFD_LONG:
- if (entry->length == 1)
+ if (count == 1)
{
item->value.vt = VT_UI4;
- item->value.u.ulVal = entry->value;
+ item->value.u.ulVal = value;
break;
}
FIXME("loading multiple long fields is not implemented\n");
break;
case IFD_RATIONAL:
- if (entry->length == 1)
+ if (count == 1)
{
HRESULT hr;
LARGE_INTEGER pos;
struct IFD_rational rational;
- pos.QuadPart = entry->value;
+ pos.QuadPart = 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);
+ hr = IStream_Read(input, &rational, sizeof(rational), NULL);
if (FAILED(hr)) return hr;
item->value.u.uhVal.QuadPart = ((LONGLONG)rational.denominator << 32) | rational.numerator;
+ SWAP_ULONGLONG(item->value.u.uhVal.QuadPart);
break;
}
FIXME("loading multiple rational fields is not implemented\n");
@@ -688,12 +707,22 @@ static HRESULT LoadIfdMetadata(IStream *input, const GUID *preferred_vendor,
MetadataItem *result;
USHORT count, i;
struct IFD_entry *entry;
+ BOOL native_byte_order = TRUE;
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), NULL);
if (FAILED(hr)) return hr;
+ SWAP_USHORT(count);
+
entry = HeapAlloc(GetProcessHeap(), 0, count * sizeof(*entry));
if (!entry) return E_OUTOFMEMORY;
@@ -713,7 +742,7 @@ static HRESULT LoadIfdMetadata(IStream *input, const GUID *preferred_vendor,
for (i = 0; i < count; i++)
{
- hr = load_IFD_entry(input, &entry[i], &result[i]);
+ hr = load_IFD_entry(input, &entry[i], &result[i], native_byte_order);
if (FAILED(hr))
{
HeapFree(GetProcessHeap(), 0, entry);
--
1.7.10.1
More information about the wine-patches
mailing list