Implemented OleLoadPicture.
Added support for loading JPEG, Bitmap and Icons from persistant streams. Implemented JPEG support using libjpeg, added necessary configure.in options. Added IConnectionPoint style notifications to the IPicture iface. Implemented several of the stubs already there, added some more.
This commit is contained in:
parent
822ab45314
commit
252b0fe099
10
configure.in
10
configure.in
|
@ -122,6 +122,16 @@ AC_CHECK_HEADERS(dlfcn.h,
|
|||
LIBEXT="a"
|
||||
)
|
||||
|
||||
JPEGLIB=""
|
||||
AC_SUBST(JPEGLIB)
|
||||
AC_CHECK_HEADERS(jpeglib.h,
|
||||
AC_CHECK_LIB(jpeg,jpeg_start_decompress,
|
||||
AC_DEFINE(HAVE_LIBJPEG,1,[Define if you have libjpeg including devel headers])
|
||||
JPEGLIB="-ljpeg"
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
AC_SUBST(XLIB)
|
||||
AC_SUBST(X_DLLS)
|
||||
X_DLLS=""
|
||||
|
|
|
@ -4,7 +4,7 @@ SRCDIR = @srcdir@
|
|||
VPATH = @srcdir@
|
||||
MODULE = oleaut32
|
||||
ALTNAMES = ole2disp typelib
|
||||
EXTRALIBS = $(LIBUUID)
|
||||
EXTRALIBS = $(LIBUUID) @JPEGLIB@
|
||||
|
||||
LDDLLFLAGS = @LDDLLFLAGS@
|
||||
SYMBOLFILE = $(MODULE).tmp.o
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
* Implementation of OLE IPicture and related interfaces
|
||||
*
|
||||
* Copyright 2000 Huw D M Davies for CodeWeavers.
|
||||
* Copyright 2001 Marcus Meissner
|
||||
*
|
||||
*
|
||||
* BUGS
|
||||
*
|
||||
* Only implements PICTYPE_BITMAP.
|
||||
* Most methods are just stubs.
|
||||
* Doesn't even expose IPersistStream, IConnectionPointContainer.
|
||||
* Support PICTYPE_BITMAP and PICTYPE_ICON, altough only bitmaps very well..
|
||||
* Lots of methods are just stubs.
|
||||
*
|
||||
*
|
||||
* NOTES (or things that msdn doesn't tell you)
|
||||
|
@ -22,6 +22,8 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "winerror.h"
|
||||
#include "winbase.h"
|
||||
|
@ -29,9 +31,21 @@
|
|||
#include "winuser.h"
|
||||
#include "ole2.h"
|
||||
#include "olectl.h"
|
||||
#include "oleauto.h"
|
||||
#include "wine/obj_picture.h"
|
||||
#include "wine/obj_connection.h"
|
||||
#include "connpt.h"
|
||||
#include "debugtools.h"
|
||||
|
||||
#include "wine/wingdi16.h"
|
||||
#include "cursoricon.h"
|
||||
|
||||
#ifdef HAVE_LIBJPEG
|
||||
/* This is a hack, so jpeglib.h does not redefine INT32 and the like*/
|
||||
#define XMD_H
|
||||
#include <jpeglib.h>
|
||||
#endif
|
||||
|
||||
DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -47,6 +61,7 @@ typedef struct OLEPictureImpl {
|
|||
ICOM_VTABLE(IPicture) *lpvtbl1;
|
||||
ICOM_VTABLE(IDispatch) *lpvtbl2;
|
||||
ICOM_VTABLE(IPersistStream) *lpvtbl3;
|
||||
ICOM_VTABLE(IConnectionPointContainer) *lpvtbl4;
|
||||
|
||||
/* Object referenece count */
|
||||
DWORD ref;
|
||||
|
@ -65,6 +80,10 @@ typedef struct OLEPictureImpl {
|
|||
OLE_XSIZE_HIMETRIC himetricWidth;
|
||||
OLE_YSIZE_HIMETRIC himetricHeight;
|
||||
|
||||
IConnectionPoint *pCP;
|
||||
|
||||
BOOL keepOrigFormat;
|
||||
HDC hDCCur;
|
||||
} OLEPictureImpl;
|
||||
|
||||
/*
|
||||
|
@ -72,9 +91,10 @@ typedef struct OLEPictureImpl {
|
|||
*/
|
||||
#define ICOM_THIS_From_IDispatch(impl, name) \
|
||||
impl *This = (impl*)(((char*)name)-sizeof(void*));
|
||||
|
||||
#define ICOM_THIS_From_IPersistStream(impl, name) \
|
||||
impl *This = (impl*)(((char*)name)-2*sizeof(void*));
|
||||
#define ICOM_THIS_From_IConnectionPointContainer(impl, name) \
|
||||
impl *This = (impl*)(((char*)name)-3*sizeof(void*));
|
||||
|
||||
/*
|
||||
* Predeclare VTables. They get initialized at the end.
|
||||
|
@ -82,11 +102,33 @@ typedef struct OLEPictureImpl {
|
|||
static ICOM_VTABLE(IPicture) OLEPictureImpl_VTable;
|
||||
static ICOM_VTABLE(IDispatch) OLEPictureImpl_IDispatch_VTable;
|
||||
static ICOM_VTABLE(IPersistStream) OLEPictureImpl_IPersistStream_VTable;
|
||||
static ICOM_VTABLE(IConnectionPointContainer) OLEPictureImpl_IConnectionPointContainer_VTable;
|
||||
|
||||
/***********************************************************************
|
||||
* Implementation of the OLEPictureImpl class.
|
||||
*/
|
||||
|
||||
static void OLEPictureImpl_SetBitmap(OLEPictureImpl*This) {
|
||||
BITMAP bm;
|
||||
HDC hdcRef;
|
||||
|
||||
TRACE("bitmap handle %08x\n", This->desc.u.bmp.hbitmap);
|
||||
if(GetObjectA(This->desc.u.bmp.hbitmap, sizeof(bm), &bm) != sizeof(bm)) {
|
||||
ERR("GetObject fails\n");
|
||||
return;
|
||||
}
|
||||
This->origWidth = bm.bmWidth;
|
||||
This->origHeight = bm.bmHeight;
|
||||
/* The width and height are stored in HIMETRIC units (0.01 mm),
|
||||
so we take our pixel width divide by pixels per inch and
|
||||
multiply by 25.4 * 100 */
|
||||
/* Should we use GetBitmapDimension if available? */
|
||||
hdcRef = CreateCompatibleDC(0);
|
||||
This->himetricWidth =(bm.bmWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX);
|
||||
This->himetricHeight=(bm.bmHeight*2540)/GetDeviceCaps(hdcRef, LOGPIXELSY);
|
||||
DeleteDC(hdcRef);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* OLEPictureImpl_Construct
|
||||
*
|
||||
|
@ -99,7 +141,9 @@ static ICOM_VTABLE(IPersistStream) OLEPictureImpl_IPersistStream_VTable;
|
|||
static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn)
|
||||
{
|
||||
OLEPictureImpl* newObject = 0;
|
||||
TRACE("(%p) type = %d\n", pictDesc, pictDesc->picType);
|
||||
|
||||
if (pictDesc)
|
||||
TRACE("(%p) type = %d\n", pictDesc, pictDesc->picType);
|
||||
|
||||
/*
|
||||
* Allocate space for the object.
|
||||
|
@ -115,63 +159,49 @@ static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn)
|
|||
newObject->lpvtbl1 = &OLEPictureImpl_VTable;
|
||||
newObject->lpvtbl2 = &OLEPictureImpl_IDispatch_VTable;
|
||||
newObject->lpvtbl3 = &OLEPictureImpl_IPersistStream_VTable;
|
||||
newObject->lpvtbl4 = &OLEPictureImpl_IConnectionPointContainer_VTable;
|
||||
|
||||
CreateConnectionPoint((IUnknown*)newObject,&IID_IPropertyNotifySink,&newObject->pCP);
|
||||
|
||||
/*
|
||||
* Start with one reference count. The caller of this function
|
||||
* must release the interface pointer when it is done.
|
||||
*/
|
||||
newObject->ref = 1;
|
||||
newObject->ref = 1;
|
||||
newObject->hDCCur = 0;
|
||||
|
||||
newObject->fOwn = fOwn;
|
||||
newObject->fOwn = fOwn;
|
||||
|
||||
if(pictDesc->cbSizeofstruct != sizeof(PICTDESC)) {
|
||||
FIXME("struct size = %d\n", pictDesc->cbSizeofstruct);
|
||||
}
|
||||
memcpy(&newObject->desc, pictDesc, sizeof(PICTDESC));
|
||||
/* dunno about original value */
|
||||
newObject->keepOrigFormat = TRUE;
|
||||
|
||||
switch(pictDesc->picType) {
|
||||
case PICTYPE_BITMAP:
|
||||
{
|
||||
BITMAP bm;
|
||||
HDC hdcRef;
|
||||
if (pictDesc) {
|
||||
if(pictDesc->cbSizeofstruct != sizeof(PICTDESC)) {
|
||||
FIXME("struct size = %d\n", pictDesc->cbSizeofstruct);
|
||||
}
|
||||
memcpy(&newObject->desc, pictDesc, sizeof(PICTDESC));
|
||||
|
||||
TRACE("bitmap handle %08x\n", pictDesc->u.bmp.hbitmap);
|
||||
if(GetObjectA(pictDesc->u.bmp.hbitmap, sizeof(bm), &bm) != sizeof(bm)) {
|
||||
ERR("GetObject fails\n");
|
||||
|
||||
switch(pictDesc->picType) {
|
||||
case PICTYPE_BITMAP:
|
||||
OLEPictureImpl_SetBitmap(newObject);
|
||||
break;
|
||||
|
||||
case PICTYPE_METAFILE:
|
||||
TRACE("metafile handle %08x\n", pictDesc->u.wmf.hmeta);
|
||||
newObject->himetricWidth = pictDesc->u.wmf.xExt;
|
||||
newObject->himetricHeight = pictDesc->u.wmf.yExt;
|
||||
break;
|
||||
|
||||
case PICTYPE_ICON:
|
||||
case PICTYPE_ENHMETAFILE:
|
||||
default:
|
||||
FIXME("Unsupported type %d\n", pictDesc->picType);
|
||||
newObject->himetricWidth = newObject->himetricHeight = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
newObject->origWidth = bm.bmWidth;
|
||||
newObject->origHeight = bm.bmHeight;
|
||||
|
||||
/* The width and height are stored in HIMETRIC units (0.01 mm),
|
||||
so we take our pixel width divide by pixels per inch and
|
||||
multiply by 25.4 * 100 */
|
||||
|
||||
/* Should we use GetBitmapDimension if available? */
|
||||
|
||||
hdcRef = CreateCompatibleDC(0);
|
||||
|
||||
newObject->himetricWidth = (bm.bmWidth * 2540) /
|
||||
GetDeviceCaps(hdcRef, LOGPIXELSX);
|
||||
newObject->himetricHeight = (bm.bmHeight * 2540) /
|
||||
GetDeviceCaps(hdcRef, LOGPIXELSY);
|
||||
DeleteDC(hdcRef);
|
||||
}
|
||||
break;
|
||||
|
||||
case PICTYPE_METAFILE:
|
||||
TRACE("metafile handle %08x\n", pictDesc->u.wmf.hmeta);
|
||||
newObject->himetricWidth = pictDesc->u.wmf.xExt;
|
||||
newObject->himetricHeight = pictDesc->u.wmf.yExt;
|
||||
break;
|
||||
|
||||
case PICTYPE_ICON:
|
||||
case PICTYPE_ENHMETAFILE:
|
||||
default:
|
||||
FIXME("Unsupported type %d\n", pictDesc->picType);
|
||||
newObject->himetricWidth = newObject->himetricHeight = 0;
|
||||
break;
|
||||
} else {
|
||||
newObject->desc.picType = PICTYPE_UNINITIALIZED;
|
||||
}
|
||||
|
||||
TRACE("returning %p\n", newObject);
|
||||
|
@ -255,11 +285,14 @@ static HRESULT WINAPI OLEPictureImpl_QueryInterface(
|
|||
{
|
||||
*ppvObject = (IDispatch*)&(This->lpvtbl2);
|
||||
}
|
||||
/* else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
|
||||
else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
|
||||
{
|
||||
*ppvObject = (IPersistStream*)&(This->lpvtbl3);
|
||||
}*/
|
||||
|
||||
}
|
||||
else if (memcmp(&IID_IConnectionPointContainer, riid, sizeof(IID_IConnectionPointContainer)) == 0)
|
||||
{
|
||||
*ppvObject = (IConnectionPointContainer*)&(This->lpvtbl4);
|
||||
}
|
||||
/*
|
||||
* Check that we obtained an interface.
|
||||
*/
|
||||
|
@ -277,6 +310,30 @@ static HRESULT WINAPI OLEPictureImpl_QueryInterface(
|
|||
|
||||
return S_OK;;
|
||||
}
|
||||
/***********************************************************************
|
||||
* OLEPicture_SendNotify (internal)
|
||||
*
|
||||
* Sends notification messages of changed properties to any interested
|
||||
* connections.
|
||||
*/
|
||||
static void OLEPicture_SendNotify(OLEPictureImpl* this, DISPID dispID)
|
||||
{
|
||||
IEnumConnections *pEnum;
|
||||
CONNECTDATA CD;
|
||||
|
||||
if (IConnectionPoint_EnumConnections(this->pCP, &pEnum))
|
||||
return;
|
||||
while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
|
||||
IPropertyNotifySink *sink;
|
||||
|
||||
IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
|
||||
IPropertyNotifySink_OnChanged(sink, dispID);
|
||||
IPropertyNotifySink_Release(sink);
|
||||
IUnknown_Release(CD.pUnk);
|
||||
}
|
||||
IEnumConnections_Release(pEnum);
|
||||
return;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* OLEPictureImpl_AddRef (IUnknown)
|
||||
|
@ -417,6 +474,12 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc,
|
|||
TRACE("prcWBounds (%d,%d) - (%d,%d)\n", prcWBounds->left, prcWBounds->top,
|
||||
prcWBounds->right, prcWBounds->bottom);
|
||||
|
||||
/*
|
||||
* While the documentation suggests this to be here (or after rendering?)
|
||||
* it does cause an endless recursion in my sample app. -MM 20010804
|
||||
OLEPicture_SendNotify(This,DISPID_PICT_RENDER);
|
||||
*/
|
||||
|
||||
switch(This->desc.picType) {
|
||||
case PICTYPE_BITMAP:
|
||||
{
|
||||
|
@ -441,15 +504,17 @@ static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc,
|
|||
DeleteDC(hdcBmp);
|
||||
}
|
||||
break;
|
||||
case PICTYPE_ICON:
|
||||
FIXME("Not quite correct implementation of rendering icons...\n");
|
||||
DrawIcon(hdc,x,y,This->desc.u.icon.hicon);
|
||||
break;
|
||||
|
||||
case PICTYPE_METAFILE:
|
||||
case PICTYPE_ICON:
|
||||
case PICTYPE_ENHMETAFILE:
|
||||
default:
|
||||
FIXME("type %d not implemented\n", This->desc.picType);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -461,6 +526,7 @@ static HRESULT WINAPI OLEPictureImpl_set_hPal(IPicture *iface,
|
|||
{
|
||||
ICOM_THIS(OLEPictureImpl, iface);
|
||||
FIXME("(%p)->(%08x): stub\n", This, hpal);
|
||||
OLEPicture_SendNotify(This,DISPID_PICT_HPAL);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
@ -471,8 +537,9 @@ static HRESULT WINAPI OLEPictureImpl_get_CurDC(IPicture *iface,
|
|||
HDC *phdc)
|
||||
{
|
||||
ICOM_THIS(OLEPictureImpl, iface);
|
||||
FIXME("(%p)->(%p): stub\n", This, phdc);
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p), returning %x\n", This, This->hDCCur);
|
||||
if (phdc) *phdc = This->hDCCur;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
@ -484,8 +551,20 @@ static HRESULT WINAPI OLEPictureImpl_SelectPicture(IPicture *iface,
|
|||
OLE_HANDLE *phbmpOut)
|
||||
{
|
||||
ICOM_THIS(OLEPictureImpl, iface);
|
||||
FIXME("(%p)->(%08x, %p, %p): stub\n", This, hdcIn, phdcOut, phbmpOut);
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p)->(%08x, %p, %p)\n", This, hdcIn, phdcOut, phbmpOut);
|
||||
if (This->desc.picType == PICTYPE_BITMAP) {
|
||||
SelectObject(hdcIn,This->desc.u.bmp.hbitmap);
|
||||
|
||||
if (phdcOut)
|
||||
*phdcOut = This->hDCCur;
|
||||
This->hDCCur = hdcIn;
|
||||
if (phbmpOut)
|
||||
*phbmpOut = This->desc.u.bmp.hbitmap;
|
||||
return S_OK;
|
||||
} else {
|
||||
FIXME("Don't know how to select picture type %d\n",This->desc.picType);
|
||||
return E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
@ -495,8 +574,11 @@ static HRESULT WINAPI OLEPictureImpl_get_KeepOriginalFormat(IPicture *iface,
|
|||
BOOL *pfKeep)
|
||||
{
|
||||
ICOM_THIS(OLEPictureImpl, iface);
|
||||
FIXME("(%p)->(%p): stub\n", This, pfKeep);
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p)->(%p)\n", This, pfKeep);
|
||||
if (!pfKeep)
|
||||
return E_POINTER;
|
||||
*pfKeep = This->keepOrigFormat;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
@ -506,8 +588,10 @@ static HRESULT WINAPI OLEPictureImpl_put_KeepOriginalFormat(IPicture *iface,
|
|||
BOOL keep)
|
||||
{
|
||||
ICOM_THIS(OLEPictureImpl, iface);
|
||||
FIXME("(%p)->(%d): stub\n", This, keep);
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p)->(%d)\n", This, keep);
|
||||
This->keepOrigFormat = keep;
|
||||
/* FIXME: what DISPID notification here? */
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
@ -516,8 +600,9 @@ static HRESULT WINAPI OLEPictureImpl_put_KeepOriginalFormat(IPicture *iface,
|
|||
static HRESULT WINAPI OLEPictureImpl_PictureChanged(IPicture *iface)
|
||||
{
|
||||
ICOM_THIS(OLEPictureImpl, iface);
|
||||
FIXME("(%p)->(): stub\n", This);
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p)->()\n", This);
|
||||
OLEPicture_SendNotify(This,DISPID_PICT_HANDLE);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
|
@ -540,11 +625,382 @@ static HRESULT WINAPI OLEPictureImpl_get_Attributes(IPicture *iface,
|
|||
DWORD *pdwAttr)
|
||||
{
|
||||
ICOM_THIS(OLEPictureImpl, iface);
|
||||
FIXME("(%p)->(%p): stub\n", This, pdwAttr);
|
||||
return E_NOTIMPL;
|
||||
TRACE("(%p)->(%p).\n", This, pdwAttr);
|
||||
*pdwAttr = 0;
|
||||
switch (This->desc.picType) {
|
||||
case PICTYPE_BITMAP: break; /* not 'truely' scalable, see MSDN. */
|
||||
case PICTYPE_ICON: *pdwAttr = PICTURE_TRANSPARENT;break;
|
||||
case PICTYPE_METAFILE: *pdwAttr = PICTURE_TRANSPARENT|PICTURE_SCALABLE;break;
|
||||
default:FIXME("Unknown pictype %d\n",This->desc.picType);break;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************
|
||||
* IConnectionPointContainer
|
||||
*/
|
||||
|
||||
static HRESULT WINAPI OLEPictureImpl_IConnectionPointContainer_QueryInterface(
|
||||
IConnectionPointContainer* iface,
|
||||
REFIID riid,
|
||||
VOID** ppvoid
|
||||
) {
|
||||
ICOM_THIS_From_IConnectionPointContainer(IPicture,iface);
|
||||
|
||||
return IPicture_QueryInterface(This,riid,ppvoid);
|
||||
}
|
||||
|
||||
static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_AddRef(
|
||||
IConnectionPointContainer* iface)
|
||||
{
|
||||
ICOM_THIS_From_IConnectionPointContainer(IPicture, iface);
|
||||
|
||||
return IPicture_AddRef(This);
|
||||
}
|
||||
|
||||
static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_Release(
|
||||
IConnectionPointContainer* iface)
|
||||
{
|
||||
ICOM_THIS_From_IConnectionPointContainer(IPicture, iface);
|
||||
|
||||
return IPicture_Release(This);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI OLEPictureImpl_EnumConnectionPoints(
|
||||
IConnectionPointContainer* iface,
|
||||
IEnumConnectionPoints** ppEnum
|
||||
) {
|
||||
ICOM_THIS_From_IConnectionPointContainer(IPicture, iface);
|
||||
|
||||
FIXME("(%p,%p), stub!\n",This,ppEnum);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI OLEPictureImpl_FindConnectionPoint(
|
||||
IConnectionPointContainer* iface,
|
||||
REFIID riid,
|
||||
IConnectionPoint **ppCP
|
||||
) {
|
||||
ICOM_THIS_From_IConnectionPointContainer(OLEPictureImpl, iface);
|
||||
TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppCP);
|
||||
if (!ppCP)
|
||||
return E_POINTER;
|
||||
*ppCP = NULL;
|
||||
if (IsEqualGUID(riid,&IID_IPropertyNotifySink))
|
||||
return IConnectionPoint_QueryInterface(This->pCP,&IID_IConnectionPoint,(LPVOID)ppCP);
|
||||
FIXME("tried to find connection point on %s?\n",debugstr_guid(riid));
|
||||
return 0x80040200;
|
||||
}
|
||||
/************************************************************************
|
||||
* IPersistStream
|
||||
*/
|
||||
/************************************************************************
|
||||
* OLEPictureImpl_IPersistStream_QueryInterface (IUnknown)
|
||||
*
|
||||
* See Windows documentation for more details on IUnknown methods.
|
||||
*/
|
||||
static HRESULT WINAPI OLEPictureImpl_IPersistStream_QueryInterface(
|
||||
IPersistStream* iface,
|
||||
REFIID riid,
|
||||
VOID** ppvoid)
|
||||
{
|
||||
ICOM_THIS_From_IPersistStream(IPicture, iface);
|
||||
|
||||
return IPicture_QueryInterface(This, riid, ppvoid);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* OLEPictureImpl_IPersistStream_AddRef (IUnknown)
|
||||
*
|
||||
* See Windows documentation for more details on IUnknown methods.
|
||||
*/
|
||||
static ULONG WINAPI OLEPictureImpl_IPersistStream_AddRef(
|
||||
IPersistStream* iface)
|
||||
{
|
||||
ICOM_THIS_From_IPersistStream(IPicture, iface);
|
||||
|
||||
return IPicture_AddRef(This);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* OLEPictureImpl_IPersistStream_Release (IUnknown)
|
||||
*
|
||||
* See Windows documentation for more details on IUnknown methods.
|
||||
*/
|
||||
static ULONG WINAPI OLEPictureImpl_IPersistStream_Release(
|
||||
IPersistStream* iface)
|
||||
{
|
||||
ICOM_THIS_From_IPersistStream(IPicture, iface);
|
||||
|
||||
return IPicture_Release(This);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* OLEPictureImpl_IPersistStream_GetClassID
|
||||
*/
|
||||
static HRESULT WINAPI OLEPictureImpl_GetClassID(
|
||||
IPersistStream* iface,CLSID* pClassID)
|
||||
{
|
||||
ICOM_THIS_From_IPersistStream(IPicture, iface);
|
||||
FIXME("(%p),stub!\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* OLEPictureImpl_IPersistStream_IsDirty
|
||||
*/
|
||||
static HRESULT WINAPI OLEPictureImpl_IsDirty(
|
||||
IPersistStream* iface)
|
||||
{
|
||||
ICOM_THIS_From_IPersistStream(IPicture, iface);
|
||||
FIXME("(%p),stub!\n",This);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBJPEG
|
||||
/* for the jpeg decompressor source manager. */
|
||||
static void _jpeg_init_source(j_decompress_ptr cinfo) { }
|
||||
|
||||
static boolean _jpeg_fill_input_buffer(j_decompress_ptr cinfo) {
|
||||
ERR("(), should not get here.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void _jpeg_skip_input_data(j_decompress_ptr cinfo,long num_bytes) {
|
||||
ERR("(%ld), should not get here.\n",num_bytes);
|
||||
}
|
||||
|
||||
static boolean _jpeg_resync_to_restart(j_decompress_ptr cinfo, int desired) {
|
||||
ERR("(desired=%d), should not get here.\n",desired);
|
||||
return FALSE;
|
||||
}
|
||||
static void _jpeg_term_source(j_decompress_ptr cinfo) { }
|
||||
#endif /* HAVE_LIBJPEG */
|
||||
|
||||
/************************************************************************
|
||||
* OLEPictureImpl_IPersistStream_Load (IUnknown)
|
||||
*
|
||||
* Loads the binary data from the IStream. Starts at current position.
|
||||
* There appears to be an 2 DWORD header:
|
||||
* DWORD magic;
|
||||
* DWORD len;
|
||||
*
|
||||
* Currently implemented: BITMAP, ICON, JPEG.
|
||||
*/
|
||||
static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
|
||||
HRESULT hr = E_FAIL;
|
||||
ULONG xread;
|
||||
BYTE *xbuf;
|
||||
DWORD header[2];
|
||||
WORD magic;
|
||||
ICOM_THIS_From_IPersistStream(OLEPictureImpl, iface);
|
||||
|
||||
TRACE("(%p,%p)\n",This,pStm);
|
||||
|
||||
hr=IStream_Read(pStm,header,8,&xread);
|
||||
if (hr || xread!=8) {
|
||||
FIXME("Failure while reading picture header (hr is %lx, nread is %ld).\n",hr,xread);
|
||||
return hr;
|
||||
}
|
||||
xread = 0;
|
||||
xbuf = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,header[1]);
|
||||
while (xread < header[1]) {
|
||||
ULONG nread;
|
||||
hr = IStream_Read(pStm,xbuf+xread,header[1]-xread,&nread);
|
||||
xread+=nread;
|
||||
if (hr || !nread)
|
||||
break;
|
||||
}
|
||||
if (xread != header[1])
|
||||
FIXME("Could only read %ld of %ld bytes?\n",xread,header[1]);
|
||||
|
||||
magic = xbuf[0] + (xbuf[1]<<8);
|
||||
switch (magic) {
|
||||
case 0xd8ff: { /* JPEG */
|
||||
#ifdef HAVE_LIBJPEG
|
||||
struct jpeg_decompress_struct jd;
|
||||
struct jpeg_error_mgr jerr;
|
||||
int ret;
|
||||
JDIMENSION x;
|
||||
JSAMPROW samprow;
|
||||
BITMAPINFOHEADER bmi;
|
||||
LPBYTE bits;
|
||||
HDC hdcref;
|
||||
struct jpeg_source_mgr xjsm;
|
||||
|
||||
/* This is basically so we can use in-memory data for jpeg decompression.
|
||||
* We need to have all the functions.
|
||||
*/
|
||||
xjsm.next_input_byte = xbuf;
|
||||
xjsm.bytes_in_buffer = xread;
|
||||
xjsm.init_source = _jpeg_init_source;
|
||||
xjsm.fill_input_buffer = _jpeg_fill_input_buffer;
|
||||
xjsm.skip_input_data = _jpeg_skip_input_data;
|
||||
xjsm.resync_to_restart = _jpeg_resync_to_restart;
|
||||
xjsm.term_source = _jpeg_term_source;
|
||||
|
||||
jd.err = jpeg_std_error(&jerr);
|
||||
jpeg_create_decompress(&jd);
|
||||
jd.src = &xjsm;
|
||||
ret=jpeg_read_header(&jd,TRUE);
|
||||
jpeg_start_decompress(&jd);
|
||||
if (ret != JPEG_HEADER_OK) {
|
||||
ERR("Jpeg image in stream has bad format, read header returned %d.\n",ret);
|
||||
HeapFree(GetProcessHeap(),0,xbuf);
|
||||
return E_FAIL;
|
||||
}
|
||||
bits = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(jd.output_height+1)*jd.output_width*jd.output_components);
|
||||
samprow=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,jd.output_width*jd.output_components);
|
||||
while ( jd.output_scanline<jd.output_height ) {
|
||||
x = jpeg_read_scanlines(&jd,&samprow,1);
|
||||
if (x != 1) {
|
||||
FIXME("failed to read current scanline?\n");
|
||||
break;
|
||||
}
|
||||
memcpy( bits+jd.output_scanline*jd.output_width*jd.output_components,
|
||||
samprow,
|
||||
jd.output_width*jd.output_components
|
||||
);
|
||||
}
|
||||
bmi.biSize = sizeof(bmi);
|
||||
bmi.biWidth = jd.output_width;
|
||||
bmi.biHeight = -jd.output_height;
|
||||
bmi.biPlanes = 1;
|
||||
bmi.biBitCount = jd.output_components<<3;
|
||||
bmi.biCompression = BI_RGB;
|
||||
bmi.biSizeImage = jd.output_height*jd.output_width*jd.output_components;
|
||||
bmi.biXPelsPerMeter = 0;
|
||||
bmi.biYPelsPerMeter = 0;
|
||||
bmi.biClrUsed = 0;
|
||||
bmi.biClrImportant = 0;
|
||||
|
||||
HeapFree(GetProcessHeap(),0,samprow);
|
||||
jpeg_finish_decompress(&jd);
|
||||
jpeg_destroy_decompress(&jd);
|
||||
hdcref = CreateCompatibleDC(0);
|
||||
This->desc.u.bmp.hbitmap=CreateDIBitmap(
|
||||
hdcref,
|
||||
&bmi,
|
||||
CBM_INIT,
|
||||
bits,
|
||||
(BITMAPINFO*)&bmi,
|
||||
DIB_RGB_COLORS
|
||||
);
|
||||
DeleteDC(hdcref);
|
||||
This->desc.picType = PICTYPE_BITMAP;
|
||||
OLEPictureImpl_SetBitmap(This);
|
||||
hr = S_OK;
|
||||
HeapFree(GetProcessHeap(),0,bits);
|
||||
#else
|
||||
ERR("Trying to load JPEG picture, but JPEG supported not compiled in.\n");
|
||||
hr = E_FAIL;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case 0x4d42: { /* Bitmap */
|
||||
BITMAPFILEHEADER *bfh = (BITMAPFILEHEADER*)xbuf;
|
||||
BITMAPINFO *bi = (BITMAPINFO*)(bfh+1);
|
||||
HDC hdcref;
|
||||
|
||||
/* Does not matter whether this is a coreheader or not, we only use
|
||||
* components which are in both
|
||||
*/
|
||||
hdcref = CreateCompatibleDC(0);
|
||||
This->desc.u.bmp.hbitmap = CreateDIBitmap(
|
||||
hdcref,
|
||||
&(bi->bmiHeader),
|
||||
CBM_INIT,
|
||||
xbuf+bfh->bfOffBits,
|
||||
bi,
|
||||
(bi->bmiHeader.biBitCount<=8)?DIB_PAL_COLORS:DIB_RGB_COLORS
|
||||
);
|
||||
DeleteDC(hdcref);
|
||||
This->desc.picType = PICTYPE_BITMAP;
|
||||
OLEPictureImpl_SetBitmap(This);
|
||||
hr = S_OK;
|
||||
break;
|
||||
}
|
||||
case 0x0000: { /* ICON , first word is dwReserved */
|
||||
HICON hicon;
|
||||
CURSORICONFILEDIR *cifd = (CURSORICONFILEDIR*)xbuf;
|
||||
int i;
|
||||
|
||||
/*
|
||||
FIXME("icon.idReserved=%d\n",cifd->idReserved);
|
||||
FIXME("icon.idType=%d\n",cifd->idType);
|
||||
FIXME("icon.idCount=%d\n",cifd->idCount);
|
||||
|
||||
for (i=0;i<cifd->idCount;i++) {
|
||||
FIXME("[%d] width %d\n",i,cifd->idEntries[i].bWidth);
|
||||
FIXME("[%d] height %d\n",i,cifd->idEntries[i].bHeight);
|
||||
FIXME("[%d] bColorCount %d\n",i,cifd->idEntries[i].bColorCount);
|
||||
FIXME("[%d] bReserved %d\n",i,cifd->idEntries[i].bReserved);
|
||||
FIXME("[%d] xHotspot %d\n",i,cifd->idEntries[i].xHotspot);
|
||||
FIXME("[%d] yHotspot %d\n",i,cifd->idEntries[i].yHotspot);
|
||||
FIXME("[%d] dwDIBSize %d\n",i,cifd->idEntries[i].dwDIBSize);
|
||||
FIXME("[%d] dwDIBOffset %d\n",i,cifd->idEntries[i].dwDIBOffset);
|
||||
}
|
||||
*/
|
||||
i=0;
|
||||
/* If we have more than one icon, try to find the best.
|
||||
* this currently means '32 pixel wide'.
|
||||
*/
|
||||
if (cifd->idCount!=1) {
|
||||
for (i=0;i<cifd->idCount;i++) {
|
||||
if (cifd->idEntries[i].bWidth == 32)
|
||||
break;
|
||||
}
|
||||
if (i==cifd->idCount) i=0;
|
||||
}
|
||||
|
||||
hicon = CreateIconFromResourceEx(
|
||||
xbuf+cifd->idEntries[i].dwDIBOffset,
|
||||
cifd->idEntries[i].dwDIBSize,
|
||||
TRUE, /* is icon */
|
||||
0x00030000,
|
||||
cifd->idEntries[i].bWidth,
|
||||
cifd->idEntries[i].bHeight,
|
||||
0
|
||||
);
|
||||
if (!hicon) {
|
||||
FIXME("CreateIcon failed.\n");
|
||||
hr = E_FAIL;
|
||||
} else {
|
||||
This->desc.picType = PICTYPE_ICON;
|
||||
This->desc.u.icon.hicon = hicon;
|
||||
hr = S_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
FIXME("Unknown magic %04x\n",magic);
|
||||
hr=E_FAIL;
|
||||
break;
|
||||
}
|
||||
HeapFree(GetProcessHeap(),0,xbuf);
|
||||
|
||||
/* FIXME: this notify is not really documented */
|
||||
if (hr==S_OK)
|
||||
OLEPicture_SendNotify(This,DISPID_PICT_TYPE);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI OLEPictureImpl_Save(
|
||||
IPersistStream* iface,IStream*pStm,BOOL fClearDirty)
|
||||
{
|
||||
ICOM_THIS_From_IPersistStream(IPicture, iface);
|
||||
FIXME("(%p,%p,%d),stub!\n",This,pStm,fClearDirty);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI OLEPictureImpl_GetSizeMax(
|
||||
IPersistStream* iface,ULARGE_INTEGER*pcbSize)
|
||||
{
|
||||
ICOM_THIS_From_IPersistStream(IPicture, iface);
|
||||
FIXME("(%p,%p),stub!\n",This,pcbSize);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
* IDispatch
|
||||
|
@ -654,9 +1110,12 @@ static HRESULT WINAPI OLEPictureImpl_Invoke(
|
|||
EXCEPINFO* pExepInfo,
|
||||
UINT* puArgErr)
|
||||
{
|
||||
FIXME("():Stub\n");
|
||||
FIXME("(dispid: %ld):Stub\n",dispIdMember);
|
||||
|
||||
return E_NOTIMPL;
|
||||
VariantInit(pVarResult);
|
||||
pVarResult->vt = VT_BOOL;
|
||||
pVarResult->u.boolVal = FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -694,6 +1153,29 @@ static ICOM_VTABLE(IDispatch) OLEPictureImpl_IDispatch_VTable =
|
|||
OLEPictureImpl_Invoke
|
||||
};
|
||||
|
||||
static ICOM_VTABLE(IPersistStream) OLEPictureImpl_IPersistStream_VTable =
|
||||
{
|
||||
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
||||
OLEPictureImpl_IPersistStream_QueryInterface,
|
||||
OLEPictureImpl_IPersistStream_AddRef,
|
||||
OLEPictureImpl_IPersistStream_Release,
|
||||
OLEPictureImpl_GetClassID,
|
||||
OLEPictureImpl_IsDirty,
|
||||
OLEPictureImpl_Load,
|
||||
OLEPictureImpl_Save,
|
||||
OLEPictureImpl_GetSizeMax
|
||||
};
|
||||
|
||||
static ICOM_VTABLE(IConnectionPointContainer) OLEPictureImpl_IConnectionPointContainer_VTable =
|
||||
{
|
||||
ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
|
||||
OLEPictureImpl_IConnectionPointContainer_QueryInterface,
|
||||
OLEPictureImpl_IConnectionPointContainer_AddRef,
|
||||
OLEPictureImpl_IConnectionPointContainer_Release,
|
||||
OLEPictureImpl_EnumConnectionPoints,
|
||||
OLEPictureImpl_FindConnectionPoint
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* OleCreatePictureIndirect (OLEAUT32.419)
|
||||
*/
|
||||
|
@ -740,11 +1222,32 @@ HRESULT WINAPI OleCreatePictureIndirect(LPPICTDESC lpPictDesc, REFIID riid,
|
|||
* OleLoadPicture (OLEAUT32.418)
|
||||
*/
|
||||
HRESULT WINAPI OleLoadPicture( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
|
||||
REFIID reed, LPVOID *ppvObj )
|
||||
REFIID riid, LPVOID *ppvObj )
|
||||
{
|
||||
FIXME("(%p,%ld,%d,%p,%p), not implemented\n",
|
||||
lpstream, lSize, fRunmode, reed, ppvObj);
|
||||
return S_OK;
|
||||
LPPERSISTSTREAM ps;
|
||||
IPicture *newpic;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("(%p,%ld,%d,%s,%p), partially implemented.\n",
|
||||
lpstream, lSize, fRunmode, debugstr_guid(riid), ppvObj);
|
||||
|
||||
hr = OleCreatePictureIndirect(NULL,riid,!fRunmode,(LPVOID*)&newpic);
|
||||
if (hr)
|
||||
return hr;
|
||||
hr = IPicture_QueryInterface(newpic,&IID_IPersistStream, (LPVOID*)&ps);
|
||||
if (hr) {
|
||||
FIXME("Could not get IPersistStream iface from Ole Picture?\n");
|
||||
IPicture_Release(newpic);
|
||||
*ppvObj = NULL;
|
||||
return hr;
|
||||
}
|
||||
IPersistStream_Load(ps,lpstream);
|
||||
IPersistStream_Release(ps);
|
||||
hr = IPicture_QueryInterface(newpic,riid,ppvObj);
|
||||
if (hr)
|
||||
FIXME("Failed to get interface %s from IPicture.\n",debugstr_guid(riid));
|
||||
IPicture_Release(newpic);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
|
|
@ -241,6 +241,9 @@
|
|||
/* Define if you have the <ieeefp.h> header file. */
|
||||
#undef HAVE_IEEEFP_H
|
||||
|
||||
/* Define if you have the <jpeglib.h> header file. */
|
||||
#undef HAVE_JPEGLIB_H
|
||||
|
||||
/* Define if you have the <libio.h> header file. */
|
||||
#undef HAVE_LIBIO_H
|
||||
|
||||
|
@ -418,6 +421,9 @@
|
|||
/* Define if TRACE messages are to be compiled out */
|
||||
#undef NO_TRACE_MSGS
|
||||
|
||||
/* Define if you have libjpeg including devel headers */
|
||||
#undef HAVE_LIBJPEG
|
||||
|
||||
/* Define if you have the Xpm library */
|
||||
#undef HAVE_LIBXXPM
|
||||
|
||||
|
|
|
@ -228,6 +228,14 @@ HRESULT WINAPI OleTranslateColor( OLE_COLOR clr, HPALETTE hpal,
|
|||
#define DISPID_FONT_WEIGHT 7
|
||||
#define DISPID_FONT_CHARSET 8
|
||||
|
||||
/* IPicture */
|
||||
#define DISPID_PICT_HANDLE 0
|
||||
#define DISPID_PICT_HPAL 2
|
||||
#define DISPID_PICT_TYPE 3
|
||||
#define DISPID_PICT_WIDTH 4
|
||||
#define DISPID_PICT_HEIGHT 5
|
||||
#define DISPID_PICT_RENDER 6
|
||||
|
||||
/* Reflected Window Message IDs */
|
||||
#define OCM__BASE (WM_USER+0x1c00)
|
||||
#define OCM_COMMAND (OCM__BASE + WM_COMMAND)
|
||||
|
|
|
@ -20,7 +20,10 @@ typedef LONG OLE_YPOS_HIMETRIC;
|
|||
typedef LONG OLE_XSIZE_HIMETRIC;
|
||||
typedef LONG OLE_YSIZE_HIMETRIC;
|
||||
|
||||
|
||||
typedef enum tagPicture { /* bitmasks */
|
||||
PICTURE_SCALABLE = 0x1,
|
||||
PICTURE_TRANSPARENT = 0x2
|
||||
} PICTUREATTRIBUTES;
|
||||
|
||||
/*****************************************************************************
|
||||
* Predeclare the interfaces
|
||||
|
|
Loading…
Reference in New Issue