[PATCH 2/2] ole32: Add DIB saving in data cache, and relevant tests.

Sergio Gómez Del Real sergio.g.delreal at gmail.com
Tue Nov 28 12:01:06 CST 2017


Signed-off-by: Sergio Gómez Del Real <sdelreal at codeweavers.com>
---
 dlls/ole32/datacache.c  | 49 ++++++++++++++++++++++++++++++++++++++++++-------
 dlls/ole32/tests/ole2.c | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 77 insertions(+), 7 deletions(-)

diff --git a/dlls/ole32/datacache.c b/dlls/ole32/datacache.c
index 0256957419..30cc7f27d9 100644
--- a/dlls/ole32/datacache.c
+++ b/dlls/ole32/datacache.c
@@ -838,6 +838,29 @@ static HRESULT DataCacheEntry_Save(DataCacheEntry *cache_entry, IStorage *storag
             }
             break;
         }
+        case CF_DIB:
+        {
+            header.dwSize = GlobalSize(cache_entry->stgmedium.u.hGlobal);
+            if (header.dwSize)
+            {
+                const BITMAPINFO *bmi = GlobalLock(cache_entry->stgmedium.u.hGlobal);
+                /* Size in units of 0.01mm (ie. MM_HIMETRIC) */
+                if (bmi->bmiHeader.biXPelsPerMeter != 0 && bmi->bmiHeader.biYPelsPerMeter != 0)
+                {
+                    header.dwObjectExtentX = bmi->bmiHeader.biWidth * 100000 / bmi->bmiHeader.biXPelsPerMeter;
+                    header.dwObjectExtentY = bmi->bmiHeader.biHeight * 100000 / bmi->bmiHeader.biYPelsPerMeter;
+                }
+                else
+                {
+                    HDC hdc = GetDC(0);
+                    header.dwObjectExtentX = bmi->bmiHeader.biWidth  * 2540 / GetDeviceCaps(hdc, LOGPIXELSX);
+                    header.dwObjectExtentY = bmi->bmiHeader.biHeight * 2540 / GetDeviceCaps(hdc, LOGPIXELSY);
+                    ReleaseDC(0, hdc);
+                }
+                GlobalUnlock(cache_entry->stgmedium.u.hGlobal);
+            }
+            break;
+        }
         default:
             break;
     }
@@ -866,20 +889,32 @@ static HRESULT DataCacheEntry_Save(DataCacheEntry *cache_entry, IStorage *storag
                     IStream_Release(pres_stream);
                     return DV_E_STGMEDIUM;
                 }
-                data = HeapAlloc(GetProcessHeap(), 0, header.dwSize);
-                GetMetaFileBitsEx(mfpict->hMF, header.dwSize, data);
-                GlobalUnlock(cache_entry->stgmedium.u.hMetaFilePict);
+                if (header.dwSize)
+                {
+                    data = HeapAlloc(GetProcessHeap(), 0, header.dwSize);
+                    GetMetaFileBitsEx(mfpict->hMF, header.dwSize, data);
+                    GlobalUnlock(cache_entry->stgmedium.u.hMetaFilePict);
+                    if (data)
+                    {
+                        hr = IStream_Write(pres_stream, data, header.dwSize, NULL);
+                        HeapFree(GetProcessHeap(), 0, data);
+                    }
+                }
             }
             break;
         }
+        case CF_DIB:
+        {
+            data = GlobalLock(cache_entry->stgmedium.u.hGlobal);
+            if (header.dwSize)
+                hr = IStream_Write(pres_stream, data, header.dwSize, NULL);
+            GlobalUnlock(cache_entry->stgmedium.u.hGlobal);
+            break;
+        }
         default:
             break;
     }
 
-    if (data)
-        hr = IStream_Write(pres_stream, data, header.dwSize, NULL);
-    HeapFree(GetProcessHeap(), 0, data);
-
     IStream_Release(pres_stream);
     return hr;
 }
diff --git a/dlls/ole32/tests/ole2.c b/dlls/ole32/tests/ole2.c
index 59a0fe172f..88ad207521 100644
--- a/dlls/ole32/tests/ole2.c
+++ b/dlls/ole32/tests/ole2.c
@@ -4092,6 +4092,12 @@ static IStorage *create_storage_from_def(const struct storage_def *stg_def)
     return stg;
 }
 
+static const BYTE dib_inf[] =
+{
+    0x42, 0x4d, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x36, 0x00, 0x00, 0x00
+};
+
 static const BYTE mf_rec[] =
 {
     0xd7, 0xcd, 0xc6, 0x9a, 0x00, 0x00, 0x00, 0x00,
@@ -4107,6 +4113,23 @@ static void get_stgdef(struct storage_def *stg_def, CLIPFORMAT cf, STGMEDIUM *st
 
     switch (cf)
     {
+    case CF_DIB:
+        data_size = sizeof(dib);
+        if (!strcmp(stg_def->stream[stm_idx].name, "CONTENTS"))
+        {
+            data_size += sizeof(dib_inf);
+            data = HeapAlloc(GetProcessHeap(), 0, data_size);
+            memcpy(data, dib_inf, sizeof(dib_inf));
+            memcpy(data + sizeof(dib_inf), dib, sizeof(dib));
+        }
+        else
+        {
+            data = HeapAlloc(GetProcessHeap(), 0, data_size);
+            memcpy(data, dib, sizeof(dib));
+        }
+        stg_def->stream[stm_idx].data = data;
+        stg_def->stream[stm_idx].data_size = data_size;
+        break;
     case CF_METAFILEPICT:
         mfpict = GlobalLock(U(stg_med)->hMetaFilePict);
         data_size = GetMetaFileBitsEx(mfpict->hMF, 0, NULL);
@@ -4133,6 +4156,9 @@ static void get_stgmedium(CLIPFORMAT cfFormat, STGMEDIUM *stgmedium)
 {
     switch (cfFormat)
     {
+    case CF_DIB:
+        create_dib(stgmedium);
+        break;
     case CF_METAFILEPICT:
         create_mfpict(stgmedium);
         break;
@@ -4162,6 +4188,15 @@ static void test_data_cache_save_data(void)
 
     static struct tests_data_cache *pdata, data[] =
     {
+        {
+            {
+                { CF_DIB, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL },
+            },
+            1, 1, &CLSID_WineTest,
+            {
+               &CLSID_WineTest, 1, { { "\2OlePres000", CF_DIB, DVASPECT_CONTENT, 0, NULL, 0 } }
+            }
+        },
         {
             {
                 { CF_METAFILEPICT, 0, DVASPECT_CONTENT, -1, TYMED_MFPICT },
-- 
2.14.1




More information about the wine-devel mailing list