From 8e7e2c25aae54c73bf01e521010a3a9e85509859 Mon Sep 17 00:00:00 2001 From: Mikolaj Zalewski Date: Wed, 3 Oct 2007 16:56:53 -0700 Subject: [PATCH] oleaut32: olepicture: Support loading Aldus Placable Metafiles. --- dlls/oleaut32/olepicture.c | 40 +++++++++++++++++++++- dlls/oleaut32/tests/olepicture.c | 59 +++++++++++++++++++++++++++++++- 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c index d8f01dbdafe..6608fa2914f 100644 --- a/dlls/oleaut32/olepicture.c +++ b/dlls/oleaut32/olepicture.c @@ -90,6 +90,20 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); #include "pshpack1.h" +/* Header for Aldus Placable Metafiles - a standard metafile follows */ +typedef struct _APM_HEADER +{ + DWORD key; + WORD handle; + SHORT left; + SHORT top; + SHORT right; + SHORT bottom; + WORD inch; + DWORD reserved; + WORD checksum; +} APM_HEADER; + typedef struct { BYTE bWidth; BYTE bHeight; @@ -554,8 +568,10 @@ static HRESULT WINAPI OLEPictureImpl_get_hPal(IPicture *iface, *phandle = (OLE_HANDLE)This->desc.u.bmp.hpal; hres = S_OK; break; - case PICTYPE_ICON: case PICTYPE_METAFILE: + hres = E_FAIL; + break; + case PICTYPE_ICON: case PICTYPE_ENHMETAFILE: default: FIXME("unimplemented for type %d. Returning 0 palette.\n", @@ -1690,6 +1706,25 @@ static HRESULT OLEPictureImpl_LoadMetafile(OLEPictureImpl *This, return S_OK; } +static HRESULT OLEPictureImpl_LoadAPM(OLEPictureImpl *This, + const BYTE *data, ULONG size) +{ + APM_HEADER *header = (APM_HEADER *)data; + HRESULT hr; + + if (size < sizeof(APM_HEADER)) + return E_FAIL; + if (header->key != 0x9ac6cdd7) + return E_FAIL; + + if ((hr = OLEPictureImpl_LoadMetafile(This, data + sizeof(APM_HEADER), size - sizeof(*header))) != S_OK) + return hr; + + This->himetricWidth = MulDiv((INT)header->right - header->left, 2540, header->inch); + This->himetricHeight = MulDiv((INT)header->bottom - header->top, 2540, header->inch); + return S_OK; +} + /************************************************************************ * OLEPictureImpl_IPersistStream_Load (IUnknown) * @@ -1848,6 +1883,9 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) { case 0x5089: /* PNG */ hr = OLEPictureImpl_LoadPNG(This, xbuf, xread); break; + case 0xcdd7: /* APM */ + hr = OLEPictureImpl_LoadAPM(This, xbuf, xread); + break; case 0x0000: { /* ICON , first word is dwReserved */ hr = OLEPictureImpl_LoadIcon(This, xbuf, xread); break; diff --git a/dlls/oleaut32/tests/olepicture.c b/dlls/oleaut32/tests/olepicture.c index 99cefd26fb8..c0d0de9d969 100644 --- a/dlls/oleaut32/tests/olepicture.c +++ b/dlls/oleaut32/tests/olepicture.c @@ -27,7 +27,7 @@ #define COBJMACROS -#include +#include "wine/test.h" #include #include #include @@ -40,6 +40,15 @@ #include #include +#define expect_eq(expr, value, type, format) { type ret = (expr); ok((value) == ret, #expr " expected " format " got " format "\n", value, ret); } + +#define ole_expect(expr, expect) { \ + HRESULT r = expr; \ + ok(r == (expect), #expr " returned %x, expected %s (%x)\n", r, #expect, expect); \ +} + +#define ole_check(expr) ole_expect(expr, S_OK); + static HMODULE hOleaut32; static HRESULT (WINAPI *pOleLoadPicture)(LPSTREAM,LONG,BOOL,REFIID,LPVOID*); @@ -103,6 +112,15 @@ static const unsigned char gif4pixel[42] = { 0x02,0x00,0x00,0x02,0x03,0x14,0x16,0x05,0x00,0x3b }; +/* APM with an empty metafile with some padding zeros - looks like under Window the + * metafile data should be at least 20 bytes */ +static const unsigned char apmdata[] = { +0xd7,0xcd,0xc6,0x9a, 0x00,0x00,0x00,0x00, 0x00,0x00,0xee,0x02, 0xb1,0x03,0xa0,0x05, +0x00,0x00,0x00,0x00, 0xee,0x53,0x01,0x00, 0x09,0x00,0x00,0x03, 0x13,0x00,0x00,0x00, +0x01,0x00,0x05,0x00, 0x00,0x00,0x00,0x00, 0x03,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00 +}; + struct NoStatStreamImpl { const IStreamVtbl *lpVtbl; @@ -424,6 +442,44 @@ static void test_OleCreatePictureIndirect(void) IPicture_Release(pict); } +static void test_apm() +{ + OLE_HANDLE handle; + LPSTREAM stream; + IPicture *pict; + HGLOBAL hglob; + LPBYTE *data; + LONG cxy; + BOOL keep; + short type; + + hglob = GlobalAlloc (0, sizeof(apmdata)); + data = GlobalLock(hglob); + memcpy(data, apmdata, sizeof(apmdata)); + + ole_check(CreateStreamOnHGlobal(hglob, TRUE, &stream)); + ole_check(OleLoadPictureEx(stream, sizeof(apmdata), TRUE, &IID_IPicture, 100, 100, 0, (LPVOID *)&pict)); + + ole_check(IPicture_get_Handle(pict, &handle)); + ok(handle != 0, "handle is null\n"); + + ole_check(IPicture_get_Type(pict, &type)); + expect_eq(type, PICTYPE_METAFILE, short, "%d"); + + ole_check(IPicture_get_Height(pict, &cxy)); + expect_eq(cxy, 1667, LONG, "%d"); + + ole_check(IPicture_get_Width(pict, &cxy)); + expect_eq(cxy, 1323, LONG, "%d"); + + ole_check(IPicture_get_KeepOriginalFormat(pict, &keep)); + todo_wine expect_eq(keep, FALSE, LONG, "%d"); + + ole_expect(IPicture_get_hPal(pict, &handle), E_FAIL); + IPicture_Release(pict); + IStream_Release(stream); +} + START_TEST(olepicture) { hOleaut32 = GetModuleHandleA("oleaut32.dll"); @@ -444,6 +500,7 @@ START_TEST(olepicture) if (0) test_pic(pngimage, sizeof(pngimage)); test_empty_image(); test_empty_image_2(); + test_apm(); test_Invoke(); test_OleCreatePictureIndirect();