[PATCH] oleaut32: preferentially load icons having the desired size in OleLoadPictureEx

Damjan Jovanovic damjan.jov at gmail.com
Sat Feb 29 01:21:55 CST 2020


Currently OleLoadPictureEx() ignores the caller-desired icon size
and always loads the 32x32 icon, which sometimes has to be
scaled down to 16x16, resulting in quality loss. Change this
to load the icon having the desired size, falling back to 32x32
only when the desired size is unavailable.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=20732

Signed-off-by: Damjan Jovanovic <damjan.jov at gmail.com>
---
 dlls/oleaut32/olepicture.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)
-------------- next part --------------
diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c
index 43a92ca58f..94231481be 100644
--- a/dlls/oleaut32/olepicture.c
+++ b/dlls/oleaut32/olepicture.c
@@ -151,6 +151,8 @@ typedef struct OLEPictureImpl {
     BOOL bIsDirty;                  /* Set to TRUE if picture has changed */
     unsigned int loadtime_magic;    /* If a length header was found, saves value */
     unsigned int loadtime_format;   /* for PICTYPE_BITMAP only, keeps track of image format (GIF/BMP/JPEG) */
+    DWORD desiredWidth;
+    DWORD desiredHeight;
 } OLEPictureImpl;
 
 static inline OLEPictureImpl *impl_from_IPicture(IPicture *iface)
@@ -1251,14 +1253,20 @@ static HRESULT OLEPictureImpl_LoadIcon(OLEPictureImpl *This, BYTE *xbuf, ULONG x
         return E_FAIL;
     }
     i=0;
-    /* If we have more than one icon, try to find the best.
-     * this currently means '32 pixel wide'.
-     */
     if (cifd->idCount!=1) {
+	/* First try exact match on the desired dimensions */
 	for (i=0;i<cifd->idCount;i++) {
-	    if (cifd->idEntries[i].bWidth == 32)
+	    if (cifd->idEntries[i].bWidth == This->desiredWidth &&
+		cifd->idEntries[i].bHeight == This->desiredHeight)
 		break;
 	}
+	/* Otherwise, try to find the best. This currently means '32 pixel wide'. */
+	if (i==cifd->idCount) {
+	    for (i=0;i<cifd->idCount;i++) {
+		if (cifd->idEntries[i].bWidth == 32)
+		    break;
+	    }
+	}
 	if (i==cifd->idCount) i=0;
     }
     if (xread < cifd->idEntries[i].dwDIBOffset + cifd->idEntries[i].dwDIBSize)
@@ -2297,6 +2305,7 @@ HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
 {
   LPPERSISTSTREAM ps;
   IPicture	*newpic;
+  OLEPictureImpl *pictureImpl;
   HRESULT hr;
 
   FIXME("(%p,%d,%d,%s,x=%d,y=%d,f=%x,%p), partially implemented.\n",
@@ -2305,6 +2314,9 @@ HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
   hr = OleCreatePictureIndirect(NULL,riid,!fRunmode,(LPVOID*)&newpic);
   if (hr != S_OK)
     return hr;
+  pictureImpl = impl_from_IPicture(newpic);
+  pictureImpl->desiredWidth = xsiz;
+  pictureImpl->desiredHeight = ysiz;
   hr = IPicture_QueryInterface(newpic,&IID_IPersistStream, (LPVOID*)&ps);
   if (hr != S_OK) {
       ERR("Could not get IPersistStream iface from Ole Picture?\n");


More information about the wine-devel mailing list