[8/8] windowscodecs: Add support for loading of multiple 8-byte IFD fields.

Dmitry Timoshkov dmitry at baikal.ru
Fri Jun 15 23:24:01 CDT 2012


---
 dlls/windowscodecs/metadatahandler.c |   32 +++++++++++++++++++++++++++++++-
 dlls/windowscodecs/tests/metadata.c  |   25 ++++++++++++++++++++-----
 2 files changed, 51 insertions(+), 6 deletions(-)

diff --git a/dlls/windowscodecs/metadatahandler.c b/dlls/windowscodecs/metadatahandler.c
index b21c76f..e5a8e86 100644
--- a/dlls/windowscodecs/metadatahandler.c
+++ b/dlls/windowscodecs/metadatahandler.c
@@ -829,7 +829,37 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
             }
             break;
         }
-        FIXME("loading multiple rational fields is not implemented\n");
+        else
+        {
+            item->value.vt |= VT_VECTOR;
+            item->value.u.cauh.cElems = count;
+            item->value.u.cauh.pElems = HeapAlloc(GetProcessHeap(), 0, count * 8);
+            if (!item->value.u.cauh.pElems) return E_OUTOFMEMORY;
+
+            pos.QuadPart = value;
+            hr = IStream_Seek(input, pos, SEEK_SET, NULL);
+            if (FAILED(hr))
+            {
+                HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems);
+                return hr;
+            }
+            hr = IStream_Read(input, item->value.u.cauh.pElems, count * 8, NULL);
+            if (FAILED(hr))
+            {
+                HeapFree(GetProcessHeap(), 0, item->value.u.cauh.pElems);
+                return hr;
+            }
+            for (i = 0; i < count; i++)
+            {
+                if (type == IFD_DOUBLE)
+                    SWAP_ULONGLONG(item->value.u.cauh.pElems[i].QuadPart);
+                else
+                {
+                    SWAP_ULONG(item->value.u.cauh.pElems[i].u.LowPart);
+                    SWAP_ULONG(item->value.u.cauh.pElems[i].u.HighPart);
+                }
+            }
+        }
         break;
     case IFD_ASCII:
         item->value.u.pszVal = HeapAlloc(GetProcessHeap(), 0, count + 1);
diff --git a/dlls/windowscodecs/tests/metadata.c b/dlls/windowscodecs/tests/metadata.c
index 97f90b1..b72956b 100644
--- a/dlls/windowscodecs/tests/metadata.c
+++ b/dlls/windowscodecs/tests/metadata.c
@@ -75,10 +75,11 @@ static const struct
     struct IFD_entry entry[40];
     ULONG next_IFD;
     struct IFD_rational xres;
-    char string[13];
+    char string[14];
+    struct IFD_rational rational[3];
 } IFD_data =
 {
-    26,
+    27,
     {
         { 0xfe,  IFD_SHORT, 1, 1 }, /* NEWSUBFILETYPE */
         { 0x100, IFD_LONG, 1, 222 }, /* IMAGEWIDTH */
@@ -115,10 +116,13 @@ static const struct
         { 0xf012, IFD_SHORT, 0, 0x11223344 },
         { 0xf013, IFD_LONG, 0, 0x11223344 },
         { 0xf014, IFD_FLOAT, 0, 0x11223344 },
+        { 0xf015, IFD_SRATIONAL, 3,
+          sizeof(USHORT) + sizeof(struct IFD_entry) * 40 + sizeof(ULONG) + sizeof(struct IFD_rational) + 14 },
     },
     0,
     { 900, 3 },
-    "Hello World!"
+    "Hello World!",
+    { { 0x01020304, 0x05060708 }, { 0x10203040, 0x50607080 }, { 0x11223344, 0x55667788 } },
 };
 #include "poppack.h"
 
@@ -548,10 +552,17 @@ static void compare_ifd_metadata(IWICMetadataReader *reader, const struct test_d
             case VT_I4:
             case VT_UI4:
             case VT_R4:
-                ok(td[i].count == U(value).caul.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).caui.cElems);
+                ok(td[i].count == U(value).caul.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).caul.cElems);
                 for (j = 0; j < U(value).caul.cElems; j++)
                     ok(td[i].value[j] == U(value).caul.pElems[j], "%u: expected value[%d] %#x/%#x, got %#x\n", i, j, (ULONG)td[i].value[j], (ULONG)(td[i].value[j] >> 32), U(value).caul.pElems[j]);
                 break;
+            case VT_I8:
+            case VT_UI8:
+            case VT_R8:
+                ok(td[i].count == U(value).cauh.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).cauh.cElems);
+                for (j = 0; j < U(value).cauh.cElems; j++)
+                    ok(td[i].value[j] == U(value).cauh.pElems[j].QuadPart, "%u: expected value[%d] %08x/%08x, got %08x/%08x\n", i, j, (ULONG)td[i].value[j], (ULONG)(td[i].value[j] >> 32), U(value).cauh.pElems[j].u.LowPart, U(value).cauh.pElems[j].u.HighPart);
+                break;
             case VT_LPSTR:
                 ok(td[i].count == U(value).calpstr.cElems, "%u: expected cElems %d, got %d\n", i, td[i].count, U(value).caub.cElems);
                 for (j = 0; j < U(value).calpstr.cElems; j++)
@@ -594,7 +605,7 @@ static void compare_ifd_metadata(IWICMetadataReader *reader, const struct test_d
 
 static void test_metadata_IFD(void)
 {
-    static const struct test_data td[26] =
+    static const struct test_data td[27] =
     {
         { VT_UI2, 0xfe, 0, { 1 } },
         { VT_UI4, 0x100, 0, { 222 } },
@@ -622,6 +633,10 @@ static void test_metadata_IFD(void)
         { VT_UI2, 0xf012, 0, { 0x3344 } },
         { VT_UI4, 0xf013, 0, { 0x11223344 } },
         { VT_R4, 0xf014, 0, { 0x11223344 } },
+        { VT_I8|VT_VECTOR, 0xf015, 3,
+          { ((LONGLONG)0x05060708 << 32) | 0x01020304,
+            ((LONGLONG)0x50607080 << 32) | 0x10203040,
+            ((LONGLONG)0x55667788 << 32) | 0x11223344 } },
     };
     HRESULT hr;
     IWICMetadataReader *reader;
-- 
1.7.10.1




More information about the wine-patches mailing list