Fixed some issues found by winapi_check.
[wine/multimedia.git] / dlls / oleaut32 / olepicture.c
blobd2cb70b874387b5e07472f8e4e41a264700ddfd5
1 /*
2 * OLE Picture object
4 * Implementation of OLE IPicture and related interfaces
6 * Copyright 2000 Huw D M Davies for CodeWeavers.
7 * Copyright 2001 Marcus Meissner
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2.1 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * BUGS
25 * Support PICTYPE_BITMAP and PICTYPE_ICON, altough only bitmaps very well..
26 * Lots of methods are just stubs.
29 * NOTES (or things that msdn doesn't tell you)
31 * The width and height properties are returned in HIMETRIC units (0.01mm)
32 * IPicture::Render also uses these to select a region of the src picture.
33 * A bitmap's size is converted into these units by using the screen resolution
34 * thus an 8x8 bitmap on a 96dpi screen has a size of 212x212 (8/96 * 2540).
38 #include "config.h"
40 #ifdef HAVE_UNISTD_H
41 # include <unistd.h>
42 #endif
43 #include <stdio.h>
44 #include <string.h>
46 /* Must be before wine includes, the header has things conflicting with
47 * WINE headers.
49 #ifdef HAVE_GIF_LIB_H
50 # include <gif_lib.h>
51 #endif
53 #define NONAMELESSUNION
54 #define NONAMELESSSTRUCT
55 #include "winerror.h"
56 #include "winbase.h"
57 #include "wingdi.h"
58 #include "winuser.h"
59 #include "ole2.h"
60 #include "olectl.h"
61 #include "oleauto.h"
62 #include "wine/obj_picture.h"
63 #include "wine/obj_connection.h"
64 #include "connpt.h"
65 #include "wine/debug.h"
67 #include "wine/wingdi16.h"
68 #include "cursoricon.h"
70 #ifdef HAVE_LIBJPEG
71 /* This is a hack, so jpeglib.h does not redefine INT32 and the like*/
72 #define XMD_H
73 #define UINT8 JPEG_UINT8
74 #define UINT16 JPEG_UINT16
75 #ifdef HAVE_JPEGLIB_H
76 # include <jpeglib.h>
77 #endif
78 #undef UINT16
79 #endif
81 WINE_DEFAULT_DEBUG_CHANNEL(ole);
83 /*************************************************************************
84 * Declaration of implementation class
87 typedef struct OLEPictureImpl {
90 * IPicture handles IUnknown
93 ICOM_VTABLE(IPicture) *lpvtbl1;
94 ICOM_VTABLE(IDispatch) *lpvtbl2;
95 ICOM_VTABLE(IPersistStream) *lpvtbl3;
96 ICOM_VTABLE(IConnectionPointContainer) *lpvtbl4;
98 /* Object referenece count */
99 DWORD ref;
101 /* We own the object and must destroy it ourselves */
102 BOOL fOwn;
104 /* Picture description */
105 PICTDESC desc;
107 /* These are the pixel size of a bitmap */
108 DWORD origWidth;
109 DWORD origHeight;
111 /* And these are the size of the picture converted into HIMETRIC units */
112 OLE_XSIZE_HIMETRIC himetricWidth;
113 OLE_YSIZE_HIMETRIC himetricHeight;
115 IConnectionPoint *pCP;
117 BOOL keepOrigFormat;
118 HDC hDCCur;
120 /* data */
121 void* data;
122 int datalen;
123 } OLEPictureImpl;
126 * Macros to retrieve pointer to IUnknown (IPicture) from the other VTables.
128 #define ICOM_THIS_From_IDispatch(impl, name) \
129 impl *This = (impl*)(((char*)name)-sizeof(void*));
130 #define ICOM_THIS_From_IPersistStream(impl, name) \
131 impl *This = (impl*)(((char*)name)-2*sizeof(void*));
132 #define ICOM_THIS_From_IConnectionPointContainer(impl, name) \
133 impl *This = (impl*)(((char*)name)-3*sizeof(void*));
136 * Predeclare VTables. They get initialized at the end.
138 static ICOM_VTABLE(IPicture) OLEPictureImpl_VTable;
139 static ICOM_VTABLE(IDispatch) OLEPictureImpl_IDispatch_VTable;
140 static ICOM_VTABLE(IPersistStream) OLEPictureImpl_IPersistStream_VTable;
141 static ICOM_VTABLE(IConnectionPointContainer) OLEPictureImpl_IConnectionPointContainer_VTable;
143 /***********************************************************************
144 * Implementation of the OLEPictureImpl class.
147 static void OLEPictureImpl_SetBitmap(OLEPictureImpl*This) {
148 BITMAP bm;
149 HDC hdcRef;
151 TRACE("bitmap handle %p\n", This->desc.u.bmp.hbitmap);
152 if(GetObjectA(This->desc.u.bmp.hbitmap, sizeof(bm), &bm) != sizeof(bm)) {
153 ERR("GetObject fails\n");
154 return;
156 This->origWidth = bm.bmWidth;
157 This->origHeight = bm.bmHeight;
158 /* The width and height are stored in HIMETRIC units (0.01 mm),
159 so we take our pixel width divide by pixels per inch and
160 multiply by 25.4 * 100 */
161 /* Should we use GetBitmapDimension if available? */
162 hdcRef = CreateCompatibleDC(0);
163 This->himetricWidth =(bm.bmWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX);
164 This->himetricHeight=(bm.bmHeight*2540)/GetDeviceCaps(hdcRef, LOGPIXELSY);
165 DeleteDC(hdcRef);
168 /************************************************************************
169 * OLEPictureImpl_Construct
171 * This method will construct a new instance of the OLEPictureImpl
172 * class.
174 * The caller of this method must release the object when it's
175 * done with it.
177 static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn)
179 OLEPictureImpl* newObject = 0;
181 if (pictDesc)
182 TRACE("(%p) type = %d\n", pictDesc, pictDesc->picType);
185 * Allocate space for the object.
187 newObject = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(OLEPictureImpl));
189 if (newObject==0)
190 return newObject;
193 * Initialize the virtual function table.
195 newObject->lpvtbl1 = &OLEPictureImpl_VTable;
196 newObject->lpvtbl2 = &OLEPictureImpl_IDispatch_VTable;
197 newObject->lpvtbl3 = &OLEPictureImpl_IPersistStream_VTable;
198 newObject->lpvtbl4 = &OLEPictureImpl_IConnectionPointContainer_VTable;
200 CreateConnectionPoint((IUnknown*)newObject,&IID_IPropertyNotifySink,&newObject->pCP);
203 * Start with one reference count. The caller of this function
204 * must release the interface pointer when it is done.
206 newObject->ref = 1;
207 newObject->hDCCur = 0;
209 newObject->fOwn = fOwn;
211 /* dunno about original value */
212 newObject->keepOrigFormat = TRUE;
214 if (pictDesc) {
215 if(pictDesc->cbSizeofstruct != sizeof(PICTDESC)) {
216 FIXME("struct size = %d\n", pictDesc->cbSizeofstruct);
218 memcpy(&newObject->desc, pictDesc, sizeof(PICTDESC));
221 switch(pictDesc->picType) {
222 case PICTYPE_BITMAP:
223 OLEPictureImpl_SetBitmap(newObject);
224 break;
226 case PICTYPE_METAFILE:
227 TRACE("metafile handle %p\n", pictDesc->u.wmf.hmeta);
228 newObject->himetricWidth = pictDesc->u.wmf.xExt;
229 newObject->himetricHeight = pictDesc->u.wmf.yExt;
230 break;
232 case PICTYPE_NONE:
233 /* not sure what to do here */
234 newObject->himetricWidth = newObject->himetricHeight = 0;
235 break;
237 case PICTYPE_ICON:
238 case PICTYPE_ENHMETAFILE:
239 default:
240 FIXME("Unsupported type %d\n", pictDesc->picType);
241 newObject->himetricWidth = newObject->himetricHeight = 0;
242 break;
244 } else {
245 newObject->desc.picType = PICTYPE_UNINITIALIZED;
248 TRACE("returning %p\n", newObject);
249 return newObject;
252 /************************************************************************
253 * OLEPictureImpl_Destroy
255 * This method is called by the Release method when the reference
256 * count goes down to 0. It will free all resources used by
257 * this object. */
258 static void OLEPictureImpl_Destroy(OLEPictureImpl* Obj)
260 TRACE("(%p)\n", Obj);
262 if(Obj->fOwn) { /* We need to destroy the picture */
263 switch(Obj->desc.picType) {
264 case PICTYPE_BITMAP:
265 DeleteObject(Obj->desc.u.bmp.hbitmap);
266 break;
267 case PICTYPE_METAFILE:
268 DeleteMetaFile(Obj->desc.u.wmf.hmeta);
269 break;
270 case PICTYPE_ICON:
271 DestroyIcon(Obj->desc.u.icon.hicon);
272 break;
273 case PICTYPE_ENHMETAFILE:
274 DeleteEnhMetaFile(Obj->desc.u.emf.hemf);
275 break;
276 default:
277 FIXME("Unsupported type %d - unable to delete\n", Obj->desc.picType);
278 break;
281 if (Obj->data) HeapFree(GetProcessHeap(), 0, Obj->data);
282 HeapFree(GetProcessHeap(), 0, Obj);
285 static ULONG WINAPI OLEPictureImpl_AddRef(IPicture* iface);
287 /************************************************************************
288 * OLEPictureImpl_QueryInterface (IUnknown)
290 * See Windows documentation for more details on IUnknown methods.
292 static HRESULT WINAPI OLEPictureImpl_QueryInterface(
293 IPicture* iface,
294 REFIID riid,
295 void** ppvObject)
297 ICOM_THIS(OLEPictureImpl, iface);
298 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject);
301 * Perform a sanity check on the parameters.
303 if ( (This==0) || (ppvObject==0) )
304 return E_INVALIDARG;
307 * Initialize the return parameter.
309 *ppvObject = 0;
312 * Compare the riid with the interface IDs implemented by this object.
314 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
316 *ppvObject = (IPicture*)This;
318 else if (memcmp(&IID_IPicture, riid, sizeof(IID_IPicture)) == 0)
320 *ppvObject = (IPicture*)This;
322 else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0)
324 *ppvObject = (IDispatch*)&(This->lpvtbl2);
326 else if (memcmp(&IID_IPictureDisp, riid, sizeof(IID_IPictureDisp)) == 0)
328 *ppvObject = (IDispatch*)&(This->lpvtbl2);
330 else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
332 *ppvObject = (IPersistStream*)&(This->lpvtbl3);
334 else if (memcmp(&IID_IConnectionPointContainer, riid, sizeof(IID_IConnectionPointContainer)) == 0)
336 *ppvObject = (IConnectionPointContainer*)&(This->lpvtbl4);
339 * Check that we obtained an interface.
341 if ((*ppvObject)==0)
343 FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid));
344 return E_NOINTERFACE;
348 * Query Interface always increases the reference count by one when it is
349 * successful
351 OLEPictureImpl_AddRef((IPicture*)This);
353 return S_OK;
355 /***********************************************************************
356 * OLEPicture_SendNotify (internal)
358 * Sends notification messages of changed properties to any interested
359 * connections.
361 static void OLEPicture_SendNotify(OLEPictureImpl* this, DISPID dispID)
363 IEnumConnections *pEnum;
364 CONNECTDATA CD;
366 if (IConnectionPoint_EnumConnections(this->pCP, &pEnum))
367 return;
368 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
369 IPropertyNotifySink *sink;
371 IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
372 IPropertyNotifySink_OnChanged(sink, dispID);
373 IPropertyNotifySink_Release(sink);
374 IUnknown_Release(CD.pUnk);
376 IEnumConnections_Release(pEnum);
377 return;
380 /************************************************************************
381 * OLEPictureImpl_AddRef (IUnknown)
383 * See Windows documentation for more details on IUnknown methods.
385 static ULONG WINAPI OLEPictureImpl_AddRef(
386 IPicture* iface)
388 ICOM_THIS(OLEPictureImpl, iface);
389 TRACE("(%p)->(ref=%ld)\n", This, This->ref);
390 This->ref++;
392 return This->ref;
395 /************************************************************************
396 * OLEPictureImpl_Release (IUnknown)
398 * See Windows documentation for more details on IUnknown methods.
400 static ULONG WINAPI OLEPictureImpl_Release(
401 IPicture* iface)
403 ICOM_THIS(OLEPictureImpl, iface);
404 TRACE("(%p)->(ref=%ld)\n", This, This->ref);
407 * Decrease the reference count on this object.
409 This->ref--;
412 * If the reference count goes down to 0, perform suicide.
414 if (This->ref==0)
416 OLEPictureImpl_Destroy(This);
418 return 0;
421 return This->ref;
425 /************************************************************************
426 * OLEPictureImpl_get_Handle
428 static HRESULT WINAPI OLEPictureImpl_get_Handle(IPicture *iface,
429 OLE_HANDLE *phandle)
431 ICOM_THIS(OLEPictureImpl, iface);
432 TRACE("(%p)->(%p)\n", This, phandle);
433 switch(This->desc.picType) {
434 case PICTYPE_BITMAP:
435 *phandle = (OLE_HANDLE)This->desc.u.bmp.hbitmap;
436 break;
437 case PICTYPE_METAFILE:
438 *phandle = (OLE_HANDLE)This->desc.u.wmf.hmeta;
439 break;
440 case PICTYPE_ICON:
441 *phandle = (OLE_HANDLE)This->desc.u.icon.hicon;
442 break;
443 case PICTYPE_ENHMETAFILE:
444 *phandle = (OLE_HANDLE)This->desc.u.emf.hemf;
445 break;
446 default:
447 FIXME("Unimplemented type %d\n", This->desc.picType);
448 return E_NOTIMPL;
450 TRACE("returning handle %08x\n", *phandle);
451 return S_OK;
454 /************************************************************************
455 * OLEPictureImpl_get_hPal
457 static HRESULT WINAPI OLEPictureImpl_get_hPal(IPicture *iface,
458 OLE_HANDLE *phandle)
460 ICOM_THIS(OLEPictureImpl, iface);
461 FIXME("(%p)->(%p): stub\n", This, phandle);
462 return E_NOTIMPL;
465 /************************************************************************
466 * OLEPictureImpl_get_Type
468 static HRESULT WINAPI OLEPictureImpl_get_Type(IPicture *iface,
469 short *ptype)
471 ICOM_THIS(OLEPictureImpl, iface);
472 TRACE("(%p)->(%p): type is %d\n", This, ptype, This->desc.picType);
473 *ptype = This->desc.picType;
474 return S_OK;
477 /************************************************************************
478 * OLEPictureImpl_get_Width
480 static HRESULT WINAPI OLEPictureImpl_get_Width(IPicture *iface,
481 OLE_XSIZE_HIMETRIC *pwidth)
483 ICOM_THIS(OLEPictureImpl, iface);
484 TRACE("(%p)->(%p): width is %ld\n", This, pwidth, This->himetricWidth);
485 *pwidth = This->himetricWidth;
486 return S_OK;
489 /************************************************************************
490 * OLEPictureImpl_get_Height
492 static HRESULT WINAPI OLEPictureImpl_get_Height(IPicture *iface,
493 OLE_YSIZE_HIMETRIC *pheight)
495 ICOM_THIS(OLEPictureImpl, iface);
496 TRACE("(%p)->(%p): height is %ld\n", This, pheight, This->himetricHeight);
497 *pheight = This->himetricHeight;
498 return S_OK;
501 /************************************************************************
502 * OLEPictureImpl_Render
504 static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc,
505 long x, long y, long cx, long cy,
506 OLE_XPOS_HIMETRIC xSrc,
507 OLE_YPOS_HIMETRIC ySrc,
508 OLE_XSIZE_HIMETRIC cxSrc,
509 OLE_YSIZE_HIMETRIC cySrc,
510 LPCRECT prcWBounds)
512 ICOM_THIS(OLEPictureImpl, iface);
513 TRACE("(%p)->(%p, (%ld,%ld), (%ld,%ld) <- (%ld,%ld), (%ld,%ld), %p)\n",
514 This, hdc, x, y, cx, cy, xSrc, ySrc, cxSrc, cySrc, prcWBounds);
515 if(prcWBounds)
516 TRACE("prcWBounds (%ld,%ld) - (%ld,%ld)\n", prcWBounds->left, prcWBounds->top,
517 prcWBounds->right, prcWBounds->bottom);
520 * While the documentation suggests this to be here (or after rendering?)
521 * it does cause an endless recursion in my sample app. -MM 20010804
522 OLEPicture_SendNotify(This,DISPID_PICT_RENDER);
525 switch(This->desc.picType) {
526 case PICTYPE_BITMAP:
528 HBITMAP hbmpOld;
529 HDC hdcBmp;
531 /* Set a mapping mode that maps bitmap pixels into HIMETRIC units.
532 NB y-axis gets flipped */
534 hdcBmp = CreateCompatibleDC(0);
535 SetMapMode(hdcBmp, MM_ANISOTROPIC);
536 SetWindowOrgEx(hdcBmp, 0, 0, NULL);
537 SetWindowExtEx(hdcBmp, This->himetricWidth, This->himetricHeight, NULL);
538 SetViewportOrgEx(hdcBmp, 0, This->origHeight, NULL);
539 SetViewportExtEx(hdcBmp, This->origWidth, -This->origHeight, NULL);
541 hbmpOld = SelectObject(hdcBmp, This->desc.u.bmp.hbitmap);
543 StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCCOPY);
545 SelectObject(hdcBmp, hbmpOld);
546 DeleteDC(hdcBmp);
548 break;
549 case PICTYPE_ICON:
550 FIXME("Not quite correct implementation of rendering icons...\n");
551 DrawIcon(hdc,x,y,This->desc.u.icon.hicon);
552 break;
554 case PICTYPE_METAFILE:
555 case PICTYPE_ENHMETAFILE:
556 default:
557 FIXME("type %d not implemented\n", This->desc.picType);
558 return E_NOTIMPL;
560 return S_OK;
563 /************************************************************************
564 * OLEPictureImpl_set_hPal
566 static HRESULT WINAPI OLEPictureImpl_set_hPal(IPicture *iface,
567 OLE_HANDLE hpal)
569 ICOM_THIS(OLEPictureImpl, iface);
570 FIXME("(%p)->(%08x): stub\n", This, hpal);
571 OLEPicture_SendNotify(This,DISPID_PICT_HPAL);
572 return E_NOTIMPL;
575 /************************************************************************
576 * OLEPictureImpl_get_CurDC
578 static HRESULT WINAPI OLEPictureImpl_get_CurDC(IPicture *iface,
579 HDC *phdc)
581 ICOM_THIS(OLEPictureImpl, iface);
582 TRACE("(%p), returning %p\n", This, This->hDCCur);
583 if (phdc) *phdc = This->hDCCur;
584 return S_OK;
587 /************************************************************************
588 * OLEPictureImpl_SelectPicture
590 static HRESULT WINAPI OLEPictureImpl_SelectPicture(IPicture *iface,
591 HDC hdcIn,
592 HDC *phdcOut,
593 OLE_HANDLE *phbmpOut)
595 ICOM_THIS(OLEPictureImpl, iface);
596 TRACE("(%p)->(%p, %p, %p)\n", This, hdcIn, phdcOut, phbmpOut);
597 if (This->desc.picType == PICTYPE_BITMAP) {
598 SelectObject(hdcIn,This->desc.u.bmp.hbitmap);
600 if (phdcOut)
601 *phdcOut = This->hDCCur;
602 This->hDCCur = hdcIn;
603 if (phbmpOut)
604 *phbmpOut = (OLE_HANDLE)This->desc.u.bmp.hbitmap;
605 return S_OK;
606 } else {
607 FIXME("Don't know how to select picture type %d\n",This->desc.picType);
608 return E_FAIL;
612 /************************************************************************
613 * OLEPictureImpl_get_KeepOriginalFormat
615 static HRESULT WINAPI OLEPictureImpl_get_KeepOriginalFormat(IPicture *iface,
616 BOOL *pfKeep)
618 ICOM_THIS(OLEPictureImpl, iface);
619 TRACE("(%p)->(%p)\n", This, pfKeep);
620 if (!pfKeep)
621 return E_POINTER;
622 *pfKeep = This->keepOrigFormat;
623 return S_OK;
626 /************************************************************************
627 * OLEPictureImpl_put_KeepOriginalFormat
629 static HRESULT WINAPI OLEPictureImpl_put_KeepOriginalFormat(IPicture *iface,
630 BOOL keep)
632 ICOM_THIS(OLEPictureImpl, iface);
633 TRACE("(%p)->(%d)\n", This, keep);
634 This->keepOrigFormat = keep;
635 /* FIXME: what DISPID notification here? */
636 return S_OK;
639 /************************************************************************
640 * OLEPictureImpl_PictureChanged
642 static HRESULT WINAPI OLEPictureImpl_PictureChanged(IPicture *iface)
644 ICOM_THIS(OLEPictureImpl, iface);
645 TRACE("(%p)->()\n", This);
646 OLEPicture_SendNotify(This,DISPID_PICT_HANDLE);
647 return S_OK;
650 /************************************************************************
651 * OLEPictureImpl_SaveAsFile
653 static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface,
654 IStream *pstream,
655 BOOL SaveMemCopy,
656 LONG *pcbSize)
658 ICOM_THIS(OLEPictureImpl, iface);
659 FIXME("(%p)->(%p, %d, %p), hacked stub.\n", This, pstream, SaveMemCopy, pcbSize);
660 return IStream_Write(pstream,This->data,This->datalen,(ULONG*)pcbSize);
663 /************************************************************************
664 * OLEPictureImpl_get_Attributes
666 static HRESULT WINAPI OLEPictureImpl_get_Attributes(IPicture *iface,
667 DWORD *pdwAttr)
669 ICOM_THIS(OLEPictureImpl, iface);
670 TRACE("(%p)->(%p).\n", This, pdwAttr);
671 *pdwAttr = 0;
672 switch (This->desc.picType) {
673 case PICTYPE_BITMAP: break; /* not 'truely' scalable, see MSDN. */
674 case PICTYPE_ICON: *pdwAttr = PICTURE_TRANSPARENT;break;
675 case PICTYPE_METAFILE: *pdwAttr = PICTURE_TRANSPARENT|PICTURE_SCALABLE;break;
676 default:FIXME("Unknown pictype %d\n",This->desc.picType);break;
678 return S_OK;
682 /************************************************************************
683 * IConnectionPointContainer
686 static HRESULT WINAPI OLEPictureImpl_IConnectionPointContainer_QueryInterface(
687 IConnectionPointContainer* iface,
688 REFIID riid,
689 VOID** ppvoid
691 ICOM_THIS_From_IConnectionPointContainer(IPicture,iface);
693 return IPicture_QueryInterface(This,riid,ppvoid);
696 static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_AddRef(
697 IConnectionPointContainer* iface)
699 ICOM_THIS_From_IConnectionPointContainer(IPicture, iface);
701 return IPicture_AddRef(This);
704 static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_Release(
705 IConnectionPointContainer* iface)
707 ICOM_THIS_From_IConnectionPointContainer(IPicture, iface);
709 return IPicture_Release(This);
712 static HRESULT WINAPI OLEPictureImpl_EnumConnectionPoints(
713 IConnectionPointContainer* iface,
714 IEnumConnectionPoints** ppEnum
716 ICOM_THIS_From_IConnectionPointContainer(IPicture, iface);
718 FIXME("(%p,%p), stub!\n",This,ppEnum);
719 return E_NOTIMPL;
722 static HRESULT WINAPI OLEPictureImpl_FindConnectionPoint(
723 IConnectionPointContainer* iface,
724 REFIID riid,
725 IConnectionPoint **ppCP
727 ICOM_THIS_From_IConnectionPointContainer(OLEPictureImpl, iface);
728 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppCP);
729 if (!ppCP)
730 return E_POINTER;
731 *ppCP = NULL;
732 if (IsEqualGUID(riid,&IID_IPropertyNotifySink))
733 return IConnectionPoint_QueryInterface(This->pCP,&IID_IConnectionPoint,(LPVOID)ppCP);
734 FIXME("tried to find connection point on %s?\n",debugstr_guid(riid));
735 return 0x80040200;
737 /************************************************************************
738 * IPersistStream
740 /************************************************************************
741 * OLEPictureImpl_IPersistStream_QueryInterface (IUnknown)
743 * See Windows documentation for more details on IUnknown methods.
745 static HRESULT WINAPI OLEPictureImpl_IPersistStream_QueryInterface(
746 IPersistStream* iface,
747 REFIID riid,
748 VOID** ppvoid)
750 ICOM_THIS_From_IPersistStream(IPicture, iface);
752 return IPicture_QueryInterface(This, riid, ppvoid);
755 /************************************************************************
756 * OLEPictureImpl_IPersistStream_AddRef (IUnknown)
758 * See Windows documentation for more details on IUnknown methods.
760 static ULONG WINAPI OLEPictureImpl_IPersistStream_AddRef(
761 IPersistStream* iface)
763 ICOM_THIS_From_IPersistStream(IPicture, iface);
765 return IPicture_AddRef(This);
768 /************************************************************************
769 * OLEPictureImpl_IPersistStream_Release (IUnknown)
771 * See Windows documentation for more details on IUnknown methods.
773 static ULONG WINAPI OLEPictureImpl_IPersistStream_Release(
774 IPersistStream* iface)
776 ICOM_THIS_From_IPersistStream(IPicture, iface);
778 return IPicture_Release(This);
781 /************************************************************************
782 * OLEPictureImpl_IPersistStream_GetClassID
784 static HRESULT WINAPI OLEPictureImpl_GetClassID(
785 IPersistStream* iface,CLSID* pClassID)
787 ICOM_THIS_From_IPersistStream(IPicture, iface);
788 FIXME("(%p),stub!\n",This);
789 return E_NOTIMPL;
792 /************************************************************************
793 * OLEPictureImpl_IPersistStream_IsDirty
795 static HRESULT WINAPI OLEPictureImpl_IsDirty(
796 IPersistStream* iface)
798 ICOM_THIS_From_IPersistStream(IPicture, iface);
799 FIXME("(%p),stub!\n",This);
800 return E_NOTIMPL;
803 #ifdef HAVE_LIBJPEG
804 /* for the jpeg decompressor source manager. */
805 static void _jpeg_init_source(j_decompress_ptr cinfo) { }
807 static boolean _jpeg_fill_input_buffer(j_decompress_ptr cinfo) {
808 ERR("(), should not get here.\n");
809 return FALSE;
812 static void _jpeg_skip_input_data(j_decompress_ptr cinfo,long num_bytes) {
813 ERR("(%ld), should not get here.\n",num_bytes);
816 static boolean _jpeg_resync_to_restart(j_decompress_ptr cinfo, int desired) {
817 ERR("(desired=%d), should not get here.\n",desired);
818 return FALSE;
820 static void _jpeg_term_source(j_decompress_ptr cinfo) { }
821 #endif /* HAVE_LIBJPEG */
823 #ifdef HAVE_LIBGIF
824 struct gifdata {
825 unsigned char *data;
826 unsigned int curoff;
827 unsigned int len;
830 static int _gif_inputfunc(GifFileType *gif, GifByteType *data, int len) {
831 struct gifdata *gd = (struct gifdata*)gif->UserData;
833 if (len+gd->curoff > gd->len) {
834 FIXME("Trying to read %d bytes, but only %d available.\n",len, gd->len-gd->curoff);
835 len = gd->len - gd->curoff;
837 memcpy(data, gd->data+gd->curoff, len);
838 gd->curoff += len;
839 return len;
841 #endif
843 /************************************************************************
844 * OLEPictureImpl_IPersistStream_Load (IUnknown)
846 * Loads the binary data from the IStream. Starts at current position.
847 * There appears to be an 2 DWORD header:
848 * DWORD magic;
849 * DWORD len;
851 * Currently implemented: BITMAP, ICON, JPEG.
853 static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
854 HRESULT hr = E_FAIL;
855 ULONG xread;
856 BYTE *xbuf;
857 DWORD header[2];
858 WORD magic;
859 STATSTG statstg;
860 ICOM_THIS_From_IPersistStream(OLEPictureImpl, iface);
862 TRACE("(%p,%p)\n",This,pStm);
864 /* Sometimes we have a header, sometimes we don't. Apply some guesses to find
865 * out whether we do.
867 hr=IStream_Stat(pStm,&statstg,STATFLAG_NONAME);
868 if (hr)
869 FIXME("Stat failed with hres %lx\n",hr);
870 hr=IStream_Read(pStm,header,8,&xread);
871 if (hr || xread!=8) {
872 FIXME("Failure while reading picture header (hr is %lx, nread is %ld).\n",hr,xread);
873 return hr;
875 if (header[1] > statstg.cbSize.QuadPart) {/* Incorrect header, assume none. */
876 xread = 8;
877 xbuf = This->data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,statstg.cbSize.QuadPart);
878 memcpy(xbuf,&header,8);
879 This->datalen = statstg.cbSize.QuadPart;
880 while (xread < This->datalen) {
881 ULONG nread;
882 hr = IStream_Read(pStm,xbuf+xread,This->datalen-xread,&nread);
883 xread+=nread;
884 if (hr || !nread)
885 break;
887 if (xread != This->datalen)
888 FIXME("Could only read %ld of %d bytes in no-header case?\n",xread,This->datalen);
889 } else {
890 xread = 0;
891 xbuf = This->data = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,header[1]);
892 This->datalen = header[1];
893 while (xread < header[1]) {
894 ULONG nread;
895 hr = IStream_Read(pStm,xbuf+xread,header[1]-xread,&nread);
896 xread+=nread;
897 if (hr || !nread)
898 break;
900 if (xread != header[1])
901 FIXME("Could only read %ld of %ld bytes?\n",xread,header[1]);
903 magic = xbuf[0] + (xbuf[1]<<8);
904 switch (magic) {
905 case 0x4947: { /* GIF */
906 #ifdef HAVE_LIBGIF
907 struct gifdata gd;
908 GifFileType *gif;
909 BITMAPINFO *bmi;
910 HDC hdcref;
911 LPBYTE bytes;
912 int i,j,ret;
913 GifImageDesc *gid;
914 SavedImage *si;
915 ColorMapObject *cm;
917 gd.data = xbuf;
918 gd.curoff = 0;
919 gd.len = xread;
920 gif = DGifOpen((void*)&gd, _gif_inputfunc);
921 ret = DGifSlurp(gif);
922 if (ret == GIF_ERROR) {
923 FIXME("Failed reading GIF using libgif.\n");
924 return E_FAIL;
926 TRACE("screen height %d, width %d\n", gif->SWidth, gif->SHeight);
927 TRACE("color res %d, backgcolor %d\n", gif->SColorResolution, gif->SBackGroundColor);
928 TRACE("imgcnt %d\n", gif->ImageCount);
929 if (gif->ImageCount<1) {
930 FIXME("GIF stream does not have images inside?\n");
931 return E_FAIL;
933 TRACE("curimage: %d x %d, on %dx%d, interlace %d\n",
934 gif->Image.Width, gif->Image.Height,
935 gif->Image.Left, gif->Image.Top,
936 gif->Image.Interlace
938 /* */
939 bmi = HeapAlloc(GetProcessHeap(),0,sizeof(BITMAPINFOHEADER)+(1<<gif->SColorResolution)*sizeof(RGBQUAD));
940 bytes= HeapAlloc(GetProcessHeap(),0,gif->SWidth*gif->SHeight);
941 si = gif->SavedImages+0;
942 gid = &(si->ImageDesc);
943 cm = gid->ColorMap;
944 if (!cm) cm = gif->SColorMap;
945 for (i=0;i<(1<<gif->SColorResolution);i++) {
946 bmi->bmiColors[i].rgbRed = cm->Colors[i].Red;
947 bmi->bmiColors[i].rgbGreen = cm->Colors[i].Green;
948 bmi->bmiColors[i].rgbBlue = cm->Colors[i].Blue;
950 /* Map to in picture coordinates */
951 for (i=0;i<gid->Height;i++)
952 for (j=0;j<gid->Width;j++)
953 bytes[(gid->Top+i)*gif->SWidth+gid->Left+j]=si->RasterBits[i*gid->Width+j];
954 bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
955 bmi->bmiHeader.biWidth = gif->SWidth;
956 bmi->bmiHeader.biHeight = gif->SHeight;
957 bmi->bmiHeader.biPlanes = 1;
958 bmi->bmiHeader.biBitCount = 8;
959 bmi->bmiHeader.biCompression = BI_RGB;
960 bmi->bmiHeader.biSizeImage = gif->SWidth*gif->SHeight;
961 bmi->bmiHeader.biXPelsPerMeter = 0;
962 bmi->bmiHeader.biYPelsPerMeter = 0;
963 bmi->bmiHeader.biClrUsed = 1 << gif->SColorResolution;
964 bmi->bmiHeader.biClrImportant = 0;
966 hdcref = GetDC(0);
967 This->desc.u.bmp.hbitmap=CreateDIBitmap(
968 hdcref,
969 &bmi->bmiHeader,
970 CBM_INIT,
971 bytes,
972 bmi,
973 DIB_PAL_COLORS
975 DeleteDC(hdcref);
976 This->desc.picType = PICTYPE_BITMAP;
977 OLEPictureImpl_SetBitmap(This);
978 DGifCloseFile(gif);
979 HeapFree(GetProcessHeap(),0,bytes);
980 return S_OK;
981 #else
982 FIXME("Trying to load GIF, but no support for libgif/libungif compiled in.\n");
983 return E_FAIL;
984 #endif
985 break;
987 case 0xd8ff: { /* JPEG */
988 #ifdef HAVE_LIBJPEG
989 struct jpeg_decompress_struct jd;
990 struct jpeg_error_mgr jerr;
991 int ret;
992 JDIMENSION x;
993 JSAMPROW samprow,oldsamprow;
994 BITMAPINFOHEADER bmi;
995 LPBYTE bits;
996 HDC hdcref;
997 struct jpeg_source_mgr xjsm;
998 LPBYTE oldbits;
999 int i;
1001 /* This is basically so we can use in-memory data for jpeg decompression.
1002 * We need to have all the functions.
1004 xjsm.next_input_byte = xbuf;
1005 xjsm.bytes_in_buffer = xread;
1006 xjsm.init_source = _jpeg_init_source;
1007 xjsm.fill_input_buffer = _jpeg_fill_input_buffer;
1008 xjsm.skip_input_data = _jpeg_skip_input_data;
1009 xjsm.resync_to_restart = _jpeg_resync_to_restart;
1010 xjsm.term_source = _jpeg_term_source;
1012 jd.err = jpeg_std_error(&jerr);
1013 jpeg_create_decompress(&jd);
1014 jd.src = &xjsm;
1015 ret=jpeg_read_header(&jd,TRUE);
1016 jd.out_color_space = JCS_RGB;
1017 jpeg_start_decompress(&jd);
1018 if (ret != JPEG_HEADER_OK) {
1019 ERR("Jpeg image in stream has bad format, read header returned %d.\n",ret);
1020 HeapFree(GetProcessHeap(),0,xbuf);
1021 return E_FAIL;
1024 bits = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,
1025 (jd.output_height+1) * ((jd.output_width*jd.output_components + 3) & ~3) );
1026 samprow=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,jd.output_width*jd.output_components);
1028 oldbits = bits;
1029 oldsamprow = samprow;
1030 while ( jd.output_scanline<jd.output_height ) {
1031 x = jpeg_read_scanlines(&jd,&samprow,1);
1032 if (x != 1) {
1033 FIXME("failed to read current scanline?\n");
1034 break;
1036 /* We have to convert from RGB to BGR, see MSDN/ BITMAPINFOHEADER */
1037 for(i=0;i<jd.output_width;i++,samprow+=jd.output_components) {
1038 *(bits++) = *(samprow+2);
1039 *(bits++) = *(samprow+1);
1040 *(bits++) = *(samprow);
1042 bits = (LPBYTE)(((UINT_PTR)bits + 3) & ~3);
1043 samprow = oldsamprow;
1045 bits = oldbits;
1047 bmi.biSize = sizeof(bmi);
1048 bmi.biWidth = jd.output_width;
1049 bmi.biHeight = -jd.output_height;
1050 bmi.biPlanes = 1;
1051 bmi.biBitCount = jd.output_components<<3;
1052 bmi.biCompression = BI_RGB;
1053 bmi.biSizeImage = jd.output_height*jd.output_width*jd.output_components;
1054 bmi.biXPelsPerMeter = 0;
1055 bmi.biYPelsPerMeter = 0;
1056 bmi.biClrUsed = 0;
1057 bmi.biClrImportant = 0;
1059 HeapFree(GetProcessHeap(),0,samprow);
1060 jpeg_finish_decompress(&jd);
1061 jpeg_destroy_decompress(&jd);
1062 hdcref = GetDC(0);
1063 This->desc.u.bmp.hbitmap=CreateDIBitmap(
1064 hdcref,
1065 &bmi,
1066 CBM_INIT,
1067 bits,
1068 (BITMAPINFO*)&bmi,
1069 DIB_RGB_COLORS
1071 DeleteDC(hdcref);
1072 This->desc.picType = PICTYPE_BITMAP;
1073 OLEPictureImpl_SetBitmap(This);
1074 hr = S_OK;
1075 HeapFree(GetProcessHeap(),0,bits);
1076 #else
1077 ERR("Trying to load JPEG picture, but JPEG supported not compiled in.\n");
1078 hr = E_FAIL;
1079 #endif
1080 break;
1082 case 0x4d42: { /* Bitmap */
1083 BITMAPFILEHEADER *bfh = (BITMAPFILEHEADER*)xbuf;
1084 BITMAPINFO *bi = (BITMAPINFO*)(bfh+1);
1085 HDC hdcref;
1087 /* Does not matter whether this is a coreheader or not, we only use
1088 * components which are in both
1090 hdcref = GetDC(0);
1091 This->desc.u.bmp.hbitmap = CreateDIBitmap(
1092 hdcref,
1093 &(bi->bmiHeader),
1094 CBM_INIT,
1095 xbuf+bfh->bfOffBits,
1097 (bi->bmiHeader.biBitCount<=8)?DIB_PAL_COLORS:DIB_RGB_COLORS
1099 DeleteDC(hdcref);
1100 This->desc.picType = PICTYPE_BITMAP;
1101 OLEPictureImpl_SetBitmap(This);
1102 hr = S_OK;
1103 break;
1105 case 0x0000: { /* ICON , first word is dwReserved */
1106 HICON hicon;
1107 CURSORICONFILEDIR *cifd = (CURSORICONFILEDIR*)xbuf;
1108 int i;
1111 FIXME("icon.idReserved=%d\n",cifd->idReserved);
1112 FIXME("icon.idType=%d\n",cifd->idType);
1113 FIXME("icon.idCount=%d\n",cifd->idCount);
1115 for (i=0;i<cifd->idCount;i++) {
1116 FIXME("[%d] width %d\n",i,cifd->idEntries[i].bWidth);
1117 FIXME("[%d] height %d\n",i,cifd->idEntries[i].bHeight);
1118 FIXME("[%d] bColorCount %d\n",i,cifd->idEntries[i].bColorCount);
1119 FIXME("[%d] bReserved %d\n",i,cifd->idEntries[i].bReserved);
1120 FIXME("[%d] xHotspot %d\n",i,cifd->idEntries[i].xHotspot);
1121 FIXME("[%d] yHotspot %d\n",i,cifd->idEntries[i].yHotspot);
1122 FIXME("[%d] dwDIBSize %d\n",i,cifd->idEntries[i].dwDIBSize);
1123 FIXME("[%d] dwDIBOffset %d\n",i,cifd->idEntries[i].dwDIBOffset);
1126 i=0;
1127 /* If we have more than one icon, try to find the best.
1128 * this currently means '32 pixel wide'.
1130 if (cifd->idCount!=1) {
1131 for (i=0;i<cifd->idCount;i++) {
1132 if (cifd->idEntries[i].bWidth == 32)
1133 break;
1135 if (i==cifd->idCount) i=0;
1138 hicon = CreateIconFromResourceEx(
1139 xbuf+cifd->idEntries[i].dwDIBOffset,
1140 cifd->idEntries[i].dwDIBSize,
1141 TRUE, /* is icon */
1142 0x00030000,
1143 cifd->idEntries[i].bWidth,
1144 cifd->idEntries[i].bHeight,
1147 if (!hicon) {
1148 FIXME("CreateIcon failed.\n");
1149 hr = E_FAIL;
1150 } else {
1151 This->desc.picType = PICTYPE_ICON;
1152 This->desc.u.icon.hicon = hicon;
1153 This->himetricWidth = cifd->idEntries[i].bWidth;
1154 This->himetricHeight = cifd->idEntries[i].bHeight;
1155 hr = S_OK;
1157 break;
1159 default:
1161 int i;
1162 FIXME("Unknown magic %04x, %ld read bytes:\n",magic,xread);
1163 hr=E_FAIL;
1164 for (i=0;i<xread+8;i++) {
1165 if (i<8) MESSAGE("%02x ",((unsigned char*)&header)[i]);
1166 else MESSAGE("%02x ",xbuf[i-8]);
1167 if (i % 10 == 9) MESSAGE("\n");
1169 MESSAGE("\n");
1170 break;
1174 /* FIXME: this notify is not really documented */
1175 if (hr==S_OK)
1176 OLEPicture_SendNotify(This,DISPID_PICT_TYPE);
1177 return hr;
1180 static HRESULT WINAPI OLEPictureImpl_Save(
1181 IPersistStream* iface,IStream*pStm,BOOL fClearDirty)
1183 ICOM_THIS_From_IPersistStream(IPicture, iface);
1184 FIXME("(%p,%p,%d),stub!\n",This,pStm,fClearDirty);
1185 return E_NOTIMPL;
1188 static HRESULT WINAPI OLEPictureImpl_GetSizeMax(
1189 IPersistStream* iface,ULARGE_INTEGER*pcbSize)
1191 ICOM_THIS_From_IPersistStream(IPicture, iface);
1192 FIXME("(%p,%p),stub!\n",This,pcbSize);
1193 return E_NOTIMPL;
1196 /************************************************************************
1197 * IDispatch
1199 /************************************************************************
1200 * OLEPictureImpl_IDispatch_QueryInterface (IUnknown)
1202 * See Windows documentation for more details on IUnknown methods.
1204 static HRESULT WINAPI OLEPictureImpl_IDispatch_QueryInterface(
1205 IDispatch* iface,
1206 REFIID riid,
1207 VOID** ppvoid)
1209 ICOM_THIS_From_IDispatch(IPicture, iface);
1211 return IPicture_QueryInterface(This, riid, ppvoid);
1214 /************************************************************************
1215 * OLEPictureImpl_IDispatch_AddRef (IUnknown)
1217 * See Windows documentation for more details on IUnknown methods.
1219 static ULONG WINAPI OLEPictureImpl_IDispatch_AddRef(
1220 IDispatch* iface)
1222 ICOM_THIS_From_IDispatch(IPicture, iface);
1224 return IPicture_AddRef(This);
1227 /************************************************************************
1228 * OLEPictureImpl_IDispatch_Release (IUnknown)
1230 * See Windows documentation for more details on IUnknown methods.
1232 static ULONG WINAPI OLEPictureImpl_IDispatch_Release(
1233 IDispatch* iface)
1235 ICOM_THIS_From_IDispatch(IPicture, iface);
1237 return IPicture_Release(This);
1240 /************************************************************************
1241 * OLEPictureImpl_GetTypeInfoCount (IDispatch)
1243 * See Windows documentation for more details on IDispatch methods.
1245 static HRESULT WINAPI OLEPictureImpl_GetTypeInfoCount(
1246 IDispatch* iface,
1247 unsigned int* pctinfo)
1249 FIXME("():Stub\n");
1251 return E_NOTIMPL;
1254 /************************************************************************
1255 * OLEPictureImpl_GetTypeInfo (IDispatch)
1257 * See Windows documentation for more details on IDispatch methods.
1259 static HRESULT WINAPI OLEPictureImpl_GetTypeInfo(
1260 IDispatch* iface,
1261 UINT iTInfo,
1262 LCID lcid,
1263 ITypeInfo** ppTInfo)
1265 FIXME("():Stub\n");
1267 return E_NOTIMPL;
1270 /************************************************************************
1271 * OLEPictureImpl_GetIDsOfNames (IDispatch)
1273 * See Windows documentation for more details on IDispatch methods.
1275 static HRESULT WINAPI OLEPictureImpl_GetIDsOfNames(
1276 IDispatch* iface,
1277 REFIID riid,
1278 LPOLESTR* rgszNames,
1279 UINT cNames,
1280 LCID lcid,
1281 DISPID* rgDispId)
1283 FIXME("():Stub\n");
1285 return E_NOTIMPL;
1288 /************************************************************************
1289 * OLEPictureImpl_Invoke (IDispatch)
1291 * See Windows documentation for more details on IDispatch methods.
1293 static HRESULT WINAPI OLEPictureImpl_Invoke(
1294 IDispatch* iface,
1295 DISPID dispIdMember,
1296 REFIID riid,
1297 LCID lcid,
1298 WORD wFlags,
1299 DISPPARAMS* pDispParams,
1300 VARIANT* pVarResult,
1301 EXCEPINFO* pExepInfo,
1302 UINT* puArgErr)
1304 FIXME("(dispid: %ld):Stub\n",dispIdMember);
1306 VariantInit(pVarResult);
1307 V_VT(pVarResult) = VT_BOOL;
1308 V_UNION(pVarResult,boolVal) = FALSE;
1309 return S_OK;
1313 static ICOM_VTABLE(IPicture) OLEPictureImpl_VTable =
1315 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1316 OLEPictureImpl_QueryInterface,
1317 OLEPictureImpl_AddRef,
1318 OLEPictureImpl_Release,
1319 OLEPictureImpl_get_Handle,
1320 OLEPictureImpl_get_hPal,
1321 OLEPictureImpl_get_Type,
1322 OLEPictureImpl_get_Width,
1323 OLEPictureImpl_get_Height,
1324 OLEPictureImpl_Render,
1325 OLEPictureImpl_set_hPal,
1326 OLEPictureImpl_get_CurDC,
1327 OLEPictureImpl_SelectPicture,
1328 OLEPictureImpl_get_KeepOriginalFormat,
1329 OLEPictureImpl_put_KeepOriginalFormat,
1330 OLEPictureImpl_PictureChanged,
1331 OLEPictureImpl_SaveAsFile,
1332 OLEPictureImpl_get_Attributes
1335 static ICOM_VTABLE(IDispatch) OLEPictureImpl_IDispatch_VTable =
1337 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1338 OLEPictureImpl_IDispatch_QueryInterface,
1339 OLEPictureImpl_IDispatch_AddRef,
1340 OLEPictureImpl_IDispatch_Release,
1341 OLEPictureImpl_GetTypeInfoCount,
1342 OLEPictureImpl_GetTypeInfo,
1343 OLEPictureImpl_GetIDsOfNames,
1344 OLEPictureImpl_Invoke
1347 static ICOM_VTABLE(IPersistStream) OLEPictureImpl_IPersistStream_VTable =
1349 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1350 OLEPictureImpl_IPersistStream_QueryInterface,
1351 OLEPictureImpl_IPersistStream_AddRef,
1352 OLEPictureImpl_IPersistStream_Release,
1353 OLEPictureImpl_GetClassID,
1354 OLEPictureImpl_IsDirty,
1355 OLEPictureImpl_Load,
1356 OLEPictureImpl_Save,
1357 OLEPictureImpl_GetSizeMax
1360 static ICOM_VTABLE(IConnectionPointContainer) OLEPictureImpl_IConnectionPointContainer_VTable =
1362 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1363 OLEPictureImpl_IConnectionPointContainer_QueryInterface,
1364 OLEPictureImpl_IConnectionPointContainer_AddRef,
1365 OLEPictureImpl_IConnectionPointContainer_Release,
1366 OLEPictureImpl_EnumConnectionPoints,
1367 OLEPictureImpl_FindConnectionPoint
1370 /***********************************************************************
1371 * OleCreatePictureIndirect (OLEAUT32.419)
1373 HRESULT WINAPI OleCreatePictureIndirect(LPPICTDESC lpPictDesc, REFIID riid,
1374 BOOL fOwn, LPVOID *ppvObj )
1376 OLEPictureImpl* newPict = NULL;
1377 HRESULT hr = S_OK;
1379 TRACE("(%p,%p,%d,%p)\n", lpPictDesc, riid, fOwn, ppvObj);
1382 * Sanity check
1384 if (ppvObj==0)
1385 return E_POINTER;
1387 *ppvObj = NULL;
1390 * Try to construct a new instance of the class.
1392 newPict = OLEPictureImpl_Construct(lpPictDesc, fOwn);
1394 if (newPict == NULL)
1395 return E_OUTOFMEMORY;
1398 * Make sure it supports the interface required by the caller.
1400 hr = IPicture_QueryInterface((IPicture*)newPict, riid, ppvObj);
1403 * Release the reference obtained in the constructor. If
1404 * the QueryInterface was unsuccessful, it will free the class.
1406 IPicture_Release((IPicture*)newPict);
1408 return hr;
1412 /***********************************************************************
1413 * OleLoadPicture (OLEAUT32.418)
1415 HRESULT WINAPI OleLoadPicture( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
1416 REFIID riid, LPVOID *ppvObj )
1418 LPPERSISTSTREAM ps;
1419 IPicture *newpic;
1420 HRESULT hr;
1422 TRACE("(%p,%ld,%d,%s,%p), partially implemented.\n",
1423 lpstream, lSize, fRunmode, debugstr_guid(riid), ppvObj);
1425 hr = OleCreatePictureIndirect(NULL,riid,!fRunmode,(LPVOID*)&newpic);
1426 if (hr)
1427 return hr;
1428 hr = IPicture_QueryInterface(newpic,&IID_IPersistStream, (LPVOID*)&ps);
1429 if (hr) {
1430 FIXME("Could not get IPersistStream iface from Ole Picture?\n");
1431 IPicture_Release(newpic);
1432 *ppvObj = NULL;
1433 return hr;
1435 IPersistStream_Load(ps,lpstream);
1436 IPersistStream_Release(ps);
1437 hr = IPicture_QueryInterface(newpic,riid,ppvObj);
1438 if (hr)
1439 FIXME("Failed to get interface %s from IPicture.\n",debugstr_guid(riid));
1440 IPicture_Release(newpic);
1441 return hr;
1444 /***********************************************************************
1445 * OleLoadPictureEx (OLEAUT32.401)
1447 HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
1448 REFIID riid, DWORD xsiz, DWORD ysiz, DWORD flags, LPVOID *ppvObj )
1450 LPPERSISTSTREAM ps;
1451 IPicture *newpic;
1452 HRESULT hr;
1454 FIXME("(%p,%ld,%d,%s,x=%ld,y=%ld,f=%lx,%p), partially implemented.\n",
1455 lpstream, lSize, fRunmode, debugstr_guid(riid), xsiz, ysiz, flags, ppvObj);
1457 hr = OleCreatePictureIndirect(NULL,riid,!fRunmode,(LPVOID*)&newpic);
1458 if (hr)
1459 return hr;
1460 hr = IPicture_QueryInterface(newpic,&IID_IPersistStream, (LPVOID*)&ps);
1461 if (hr) {
1462 FIXME("Could not get IPersistStream iface from Ole Picture?\n");
1463 IPicture_Release(newpic);
1464 *ppvObj = NULL;
1465 return hr;
1467 IPersistStream_Load(ps,lpstream);
1468 IPersistStream_Release(ps);
1469 hr = IPicture_QueryInterface(newpic,riid,ppvObj);
1470 if (hr)
1471 FIXME("Failed to get interface %s from IPicture.\n",debugstr_guid(riid));
1472 IPicture_Release(newpic);
1473 return hr;
1476 /*******************************************************************************
1477 * StdPic ClassFactory
1479 typedef struct
1481 /* IUnknown fields */
1482 ICOM_VFIELD(IClassFactory);
1483 DWORD ref;
1484 } IClassFactoryImpl;
1486 static HRESULT WINAPI
1487 SPCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
1488 ICOM_THIS(IClassFactoryImpl,iface);
1490 FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
1491 return E_NOINTERFACE;
1494 static ULONG WINAPI
1495 SPCF_AddRef(LPCLASSFACTORY iface) {
1496 ICOM_THIS(IClassFactoryImpl,iface);
1497 return ++(This->ref);
1500 static ULONG WINAPI SPCF_Release(LPCLASSFACTORY iface) {
1501 ICOM_THIS(IClassFactoryImpl,iface);
1502 /* static class, won't be freed */
1503 return --(This->ref);
1506 static HRESULT WINAPI SPCF_CreateInstance(
1507 LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
1509 PICTDESC pd;
1511 FIXME("(%p,%p,%s,%p), creating stdpic with PICTYPE_NONE.\n",iface,pOuter,debugstr_guid(riid),ppobj);
1512 pd.cbSizeofstruct = sizeof(pd);
1513 pd.picType = PICTYPE_NONE;
1514 return OleCreatePictureIndirect(&pd,riid,TRUE,ppobj);
1518 static HRESULT WINAPI SPCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
1519 ICOM_THIS(IClassFactoryImpl,iface);
1520 FIXME("(%p)->(%d),stub!\n",This,dolock);
1521 return S_OK;
1524 static ICOM_VTABLE(IClassFactory) SPCF_Vtbl = {
1525 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1526 SPCF_QueryInterface,
1527 SPCF_AddRef,
1528 SPCF_Release,
1529 SPCF_CreateInstance,
1530 SPCF_LockServer
1532 static IClassFactoryImpl STDPIC_CF = {&SPCF_Vtbl, 1 };
1534 void _get_STDPIC_CF(LPVOID *ppv) { *ppv = (LPVOID)&STDPIC_CF; }