Dmitry Timoshkov : windowscodecs: Add support for loading of multiple simple IFD fields.

Alexandre Julliard julliard at winehq.org
Thu Jun 21 15:03:41 CDT 2012


Module: wine
Branch: master
Commit: aedd9271b776e037d59ade2dbec8ce1ccfd705b1
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=aedd9271b776e037d59ade2dbec8ce1ccfd705b1

Author: Dmitry Timoshkov <dmitry at baikal.ru>
Date:   Thu Jun 21 11:20:39 2012 +0900

windowscodecs: Add support for loading of multiple simple IFD fields.

---

 dlls/windowscodecs/metadatahandler.c |  106 ++++++++++++++++++++++++++++++----
 1 files changed, 94 insertions(+), 12 deletions(-)

diff --git a/dlls/windowscodecs/metadatahandler.c b/dlls/windowscodecs/metadatahandler.c
index eecbf65..5770e12 100644
--- a/dlls/windowscodecs/metadatahandler.c
+++ b/dlls/windowscodecs/metadatahandler.c
@@ -704,8 +704,10 @@ static int tag_to_vt(SHORT tag)
 static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
                               MetadataItem *item, BOOL native_byte_order)
 {
-    ULONG count, value;
+    ULONG count, value, i;
     SHORT type;
+    LARGE_INTEGER pos;
+    HRESULT hr;
 
     item->schema.vt = VT_EMPTY;
     item->id.vt = VT_UI2;
@@ -724,22 +726,84 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
     {
      case IFD_BYTE:
      case IFD_SBYTE:
-        if (count == 1)
+        if (count <= 4)
         {
-            item->value.u.bVal = *(const BYTE *)&entry->value;
+            const BYTE *data = (const BYTE *)&entry->value;
+
+            if (count == 1)
+                item->value.u.bVal = data[0];
+            else
+            {
+                item->value.vt |= VT_VECTOR;
+                item->value.u.caub.cElems = count;
+                item->value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, count);
+                memcpy(item->value.u.caub.pElems, data, count);
+            }
             break;
         }
-        FIXME("loading multiple byte fields is not implemented\n");
+
+        item->value.vt |= VT_VECTOR;
+        item->value.u.caub.cElems = count;
+        item->value.u.caub.pElems = HeapAlloc(GetProcessHeap(), 0, count);
+        if (!item->value.u.caub.pElems) return E_OUTOFMEMORY;
+
+        pos.QuadPart = value;
+        hr = IStream_Seek(input, pos, SEEK_SET, NULL);
+        if (FAILED(hr))
+        {
+            HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems);
+            return hr;
+        }
+        hr = IStream_Read(input, item->value.u.caub.pElems, count, NULL);
+        if (FAILED(hr))
+        {
+            HeapFree(GetProcessHeap(), 0, item->value.u.caub.pElems);
+            return hr;
+        }
         break;
     case IFD_SHORT:
     case IFD_SSHORT:
-        if (count == 1)
+        if (count <= 2)
         {
-            item->value.u.uiVal = *(const SHORT *)&entry->value;
-            SWAP_USHORT(item->value.u.uiVal);
+            const SHORT *data = (const SHORT *)&entry->value;
+
+            if (count == 1)
+            {
+                item->value.u.uiVal = data[0];
+                SWAP_USHORT(item->value.u.uiVal);
+            }
+            else
+            {
+                item->value.vt |= VT_VECTOR;
+                item->value.u.caui.cElems = count;
+                item->value.u.caui.pElems = HeapAlloc(GetProcessHeap(), 0, count * 2);
+                memcpy(item->value.u.caui.pElems, data, count * 2);
+                for (i = 0; i < count; i++)
+                    SWAP_USHORT(item->value.u.caui.pElems[i]);
+            }
             break;
         }
-        FIXME("loading multiple short fields is not implemented\n");
+
+        item->value.vt |= VT_VECTOR;
+        item->value.u.caui.cElems = count;
+        item->value.u.caui.pElems = HeapAlloc(GetProcessHeap(), 0, count * 2);
+        if (!item->value.u.caui.pElems) return E_OUTOFMEMORY;
+
+        pos.QuadPart = value;
+        hr = IStream_Seek(input, pos, SEEK_SET, NULL);
+        if (FAILED(hr))
+        {
+            HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems);
+            return hr;
+        }
+        hr = IStream_Read(input, item->value.u.caui.pElems, count * 2, NULL);
+        if (FAILED(hr))
+        {
+            HeapFree(GetProcessHeap(), 0, item->value.u.caui.pElems);
+            return hr;
+        }
+        for (i = 0; i < count; i++)
+            SWAP_USHORT(item->value.u.caui.pElems[i]);
         break;
     case IFD_LONG:
     case IFD_SLONG:
@@ -749,15 +813,33 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
             item->value.u.ulVal = value;
             break;
         }
-        FIXME("loading multiple long fields is not implemented\n");
+
+        item->value.vt |= VT_VECTOR;
+        item->value.u.caul.cElems = count;
+        item->value.u.caul.pElems = HeapAlloc(GetProcessHeap(), 0, count * 4);
+        if (!item->value.u.caul.pElems) return E_OUTOFMEMORY;
+
+        pos.QuadPart = value;
+        hr = IStream_Seek(input, pos, SEEK_SET, NULL);
+        if (FAILED(hr))
+        {
+            HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems);
+            return hr;
+        }
+        hr = IStream_Read(input, item->value.u.caul.pElems, count * 4, NULL);
+        if (FAILED(hr))
+        {
+            HeapFree(GetProcessHeap(), 0, item->value.u.caul.pElems);
+            return hr;
+        }
+        for (i = 0; i < count; i++)
+            SWAP_ULONG(item->value.u.caul.pElems[i]);
         break;
     case IFD_RATIONAL:
     case IFD_SRATIONAL:
     case IFD_DOUBLE:
         if (count == 1)
         {
-            HRESULT hr;
-            LARGE_INTEGER pos;
             struct IFD_rational rational;
 
             pos.QuadPart = value;
@@ -773,7 +855,7 @@ static HRESULT load_IFD_entry(IStream *input, const struct IFD_entry *entry,
         FIXME("loading multiple rational fields is not implemented\n");
         break;
     default:
-        FIXME("loading field of type %d is not implemented\n", entry->type);
+        FIXME("loading field of type %d, count %u is not implemented\n", type, count);
         break;
     }
     return S_OK;




More information about the wine-cvs mailing list