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
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).
50 #include "wine/obj_picture.h"
51 #include "wine/obj_connection.h"
53 #include "wine/debug.h"
55 #include "wine/wingdi16.h"
56 #include "cursoricon.h"
59 /* This is a hack, so jpeglib.h does not redefine INT32 and the like*/
61 #define UINT16 JPEG_UINT16
68 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
70 /*************************************************************************
71 * Declaration of implementation class
74 typedef struct OLEPictureImpl
{
77 * IPicture handles IUnknown
80 ICOM_VTABLE(IPicture
) *lpvtbl1
;
81 ICOM_VTABLE(IDispatch
) *lpvtbl2
;
82 ICOM_VTABLE(IPersistStream
) *lpvtbl3
;
83 ICOM_VTABLE(IConnectionPointContainer
) *lpvtbl4
;
85 /* Object referenece count */
88 /* We own the object and must destroy it ourselves */
91 /* Picture description */
94 /* These are the pixel size of a bitmap */
98 /* And these are the size of the picture converted into HIMETRIC units */
99 OLE_XSIZE_HIMETRIC himetricWidth
;
100 OLE_YSIZE_HIMETRIC himetricHeight
;
102 IConnectionPoint
*pCP
;
109 * Macros to retrieve pointer to IUnknown (IPicture) from the other VTables.
111 #define ICOM_THIS_From_IDispatch(impl, name) \
112 impl *This = (impl*)(((char*)name)-sizeof(void*));
113 #define ICOM_THIS_From_IPersistStream(impl, name) \
114 impl *This = (impl*)(((char*)name)-2*sizeof(void*));
115 #define ICOM_THIS_From_IConnectionPointContainer(impl, name) \
116 impl *This = (impl*)(((char*)name)-3*sizeof(void*));
119 * Predeclare VTables. They get initialized at the end.
121 static ICOM_VTABLE(IPicture
) OLEPictureImpl_VTable
;
122 static ICOM_VTABLE(IDispatch
) OLEPictureImpl_IDispatch_VTable
;
123 static ICOM_VTABLE(IPersistStream
) OLEPictureImpl_IPersistStream_VTable
;
124 static ICOM_VTABLE(IConnectionPointContainer
) OLEPictureImpl_IConnectionPointContainer_VTable
;
126 /***********************************************************************
127 * Implementation of the OLEPictureImpl class.
130 static void OLEPictureImpl_SetBitmap(OLEPictureImpl
*This
) {
134 TRACE("bitmap handle %08x\n", This
->desc
.u
.bmp
.hbitmap
);
135 if(GetObjectA(This
->desc
.u
.bmp
.hbitmap
, sizeof(bm
), &bm
) != sizeof(bm
)) {
136 ERR("GetObject fails\n");
139 This
->origWidth
= bm
.bmWidth
;
140 This
->origHeight
= bm
.bmHeight
;
141 /* The width and height are stored in HIMETRIC units (0.01 mm),
142 so we take our pixel width divide by pixels per inch and
143 multiply by 25.4 * 100 */
144 /* Should we use GetBitmapDimension if available? */
145 hdcRef
= CreateCompatibleDC(0);
146 This
->himetricWidth
=(bm
.bmWidth
*2540)/GetDeviceCaps(hdcRef
, LOGPIXELSX
);
147 This
->himetricHeight
=(bm
.bmHeight
*2540)/GetDeviceCaps(hdcRef
, LOGPIXELSY
);
151 /************************************************************************
152 * OLEPictureImpl_Construct
154 * This method will construct a new instance of the OLEPictureImpl
157 * The caller of this method must release the object when it's
160 static OLEPictureImpl
* OLEPictureImpl_Construct(LPPICTDESC pictDesc
, BOOL fOwn
)
162 OLEPictureImpl
* newObject
= 0;
165 TRACE("(%p) type = %d\n", pictDesc
, pictDesc
->picType
);
168 * Allocate space for the object.
170 newObject
= HeapAlloc(GetProcessHeap(), 0, sizeof(OLEPictureImpl
));
176 * Initialize the virtual function table.
178 newObject
->lpvtbl1
= &OLEPictureImpl_VTable
;
179 newObject
->lpvtbl2
= &OLEPictureImpl_IDispatch_VTable
;
180 newObject
->lpvtbl3
= &OLEPictureImpl_IPersistStream_VTable
;
181 newObject
->lpvtbl4
= &OLEPictureImpl_IConnectionPointContainer_VTable
;
183 CreateConnectionPoint((IUnknown
*)newObject
,&IID_IPropertyNotifySink
,&newObject
->pCP
);
186 * Start with one reference count. The caller of this function
187 * must release the interface pointer when it is done.
190 newObject
->hDCCur
= 0;
192 newObject
->fOwn
= fOwn
;
194 /* dunno about original value */
195 newObject
->keepOrigFormat
= TRUE
;
198 if(pictDesc
->cbSizeofstruct
!= sizeof(PICTDESC
)) {
199 FIXME("struct size = %d\n", pictDesc
->cbSizeofstruct
);
201 memcpy(&newObject
->desc
, pictDesc
, sizeof(PICTDESC
));
204 switch(pictDesc
->picType
) {
206 OLEPictureImpl_SetBitmap(newObject
);
209 case PICTYPE_METAFILE
:
210 TRACE("metafile handle %08x\n", pictDesc
->u
.wmf
.hmeta
);
211 newObject
->himetricWidth
= pictDesc
->u
.wmf
.xExt
;
212 newObject
->himetricHeight
= pictDesc
->u
.wmf
.yExt
;
216 case PICTYPE_ENHMETAFILE
:
218 FIXME("Unsupported type %d\n", pictDesc
->picType
);
219 newObject
->himetricWidth
= newObject
->himetricHeight
= 0;
223 newObject
->desc
.picType
= PICTYPE_UNINITIALIZED
;
226 TRACE("returning %p\n", newObject
);
230 /************************************************************************
231 * OLEPictureImpl_Destroy
233 * This method is called by the Release method when the reference
234 * count goes down to 0. It will free all resources used by
236 static void OLEPictureImpl_Destroy(OLEPictureImpl
* Obj
)
238 TRACE("(%p)\n", Obj
);
240 if(Obj
->fOwn
) { /* We need to destroy the picture */
241 switch(Obj
->desc
.picType
) {
243 DeleteObject(Obj
->desc
.u
.bmp
.hbitmap
);
245 case PICTYPE_METAFILE
:
246 DeleteMetaFile(Obj
->desc
.u
.wmf
.hmeta
);
249 DestroyIcon(Obj
->desc
.u
.icon
.hicon
);
251 case PICTYPE_ENHMETAFILE
:
252 DeleteEnhMetaFile(Obj
->desc
.u
.emf
.hemf
);
255 FIXME("Unsupported type %d - unable to delete\n", Obj
->desc
.picType
);
259 HeapFree(GetProcessHeap(), 0, Obj
);
262 static ULONG WINAPI
OLEPictureImpl_AddRef(IPicture
* iface
);
264 /************************************************************************
265 * OLEPictureImpl_QueryInterface (IUnknown)
267 * See Windows documentation for more details on IUnknown methods.
269 static HRESULT WINAPI
OLEPictureImpl_QueryInterface(
274 ICOM_THIS(OLEPictureImpl
, iface
);
275 TRACE("(%p)->(%s, %p)\n", This
, debugstr_guid(riid
), ppvObject
);
278 * Perform a sanity check on the parameters.
280 if ( (This
==0) || (ppvObject
==0) )
284 * Initialize the return parameter.
289 * Compare the riid with the interface IDs implemented by this object.
291 if (memcmp(&IID_IUnknown
, riid
, sizeof(IID_IUnknown
)) == 0)
293 *ppvObject
= (IPicture
*)This
;
295 else if (memcmp(&IID_IPicture
, riid
, sizeof(IID_IPicture
)) == 0)
297 *ppvObject
= (IPicture
*)This
;
299 else if (memcmp(&IID_IDispatch
, riid
, sizeof(IID_IDispatch
)) == 0)
301 *ppvObject
= (IDispatch
*)&(This
->lpvtbl2
);
303 else if (memcmp(&IID_IPictureDisp
, riid
, sizeof(IID_IPictureDisp
)) == 0)
305 *ppvObject
= (IDispatch
*)&(This
->lpvtbl2
);
307 else if (memcmp(&IID_IPersistStream
, riid
, sizeof(IID_IPersistStream
)) == 0)
309 *ppvObject
= (IPersistStream
*)&(This
->lpvtbl3
);
311 else if (memcmp(&IID_IConnectionPointContainer
, riid
, sizeof(IID_IConnectionPointContainer
)) == 0)
313 *ppvObject
= (IConnectionPointContainer
*)&(This
->lpvtbl4
);
316 * Check that we obtained an interface.
320 FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid
));
321 return E_NOINTERFACE
;
325 * Query Interface always increases the reference count by one when it is
328 OLEPictureImpl_AddRef((IPicture
*)This
);
332 /***********************************************************************
333 * OLEPicture_SendNotify (internal)
335 * Sends notification messages of changed properties to any interested
338 static void OLEPicture_SendNotify(OLEPictureImpl
* this, DISPID dispID
)
340 IEnumConnections
*pEnum
;
343 if (IConnectionPoint_EnumConnections(this->pCP
, &pEnum
))
345 while(IEnumConnections_Next(pEnum
, 1, &CD
, NULL
) == S_OK
) {
346 IPropertyNotifySink
*sink
;
348 IUnknown_QueryInterface(CD
.pUnk
, &IID_IPropertyNotifySink
, (LPVOID
)&sink
);
349 IPropertyNotifySink_OnChanged(sink
, dispID
);
350 IPropertyNotifySink_Release(sink
);
351 IUnknown_Release(CD
.pUnk
);
353 IEnumConnections_Release(pEnum
);
357 /************************************************************************
358 * OLEPictureImpl_AddRef (IUnknown)
360 * See Windows documentation for more details on IUnknown methods.
362 static ULONG WINAPI
OLEPictureImpl_AddRef(
365 ICOM_THIS(OLEPictureImpl
, iface
);
366 TRACE("(%p)->(ref=%ld)\n", This
, This
->ref
);
372 /************************************************************************
373 * OLEPictureImpl_Release (IUnknown)
375 * See Windows documentation for more details on IUnknown methods.
377 static ULONG WINAPI
OLEPictureImpl_Release(
380 ICOM_THIS(OLEPictureImpl
, iface
);
381 TRACE("(%p)->(ref=%ld)\n", This
, This
->ref
);
384 * Decrease the reference count on this object.
389 * If the reference count goes down to 0, perform suicide.
393 OLEPictureImpl_Destroy(This
);
402 /************************************************************************
403 * OLEPictureImpl_get_Handle
405 static HRESULT WINAPI
OLEPictureImpl_get_Handle(IPicture
*iface
,
408 ICOM_THIS(OLEPictureImpl
, iface
);
409 TRACE("(%p)->(%p)\n", This
, phandle
);
410 switch(This
->desc
.picType
) {
412 *phandle
= This
->desc
.u
.bmp
.hbitmap
;
414 case PICTYPE_METAFILE
:
415 *phandle
= This
->desc
.u
.wmf
.hmeta
;
418 *phandle
= This
->desc
.u
.icon
.hicon
;
420 case PICTYPE_ENHMETAFILE
:
421 *phandle
= This
->desc
.u
.emf
.hemf
;
424 FIXME("Unimplemented type %d\n", This
->desc
.picType
);
427 TRACE("returning handle %08x\n", *phandle
);
431 /************************************************************************
432 * OLEPictureImpl_get_hPal
434 static HRESULT WINAPI
OLEPictureImpl_get_hPal(IPicture
*iface
,
437 ICOM_THIS(OLEPictureImpl
, iface
);
438 FIXME("(%p)->(%p): stub\n", This
, phandle
);
442 /************************************************************************
443 * OLEPictureImpl_get_Type
445 static HRESULT WINAPI
OLEPictureImpl_get_Type(IPicture
*iface
,
448 ICOM_THIS(OLEPictureImpl
, iface
);
449 TRACE("(%p)->(%p): type is %d\n", This
, ptype
, This
->desc
.picType
);
450 *ptype
= This
->desc
.picType
;
454 /************************************************************************
455 * OLEPictureImpl_get_Width
457 static HRESULT WINAPI
OLEPictureImpl_get_Width(IPicture
*iface
,
458 OLE_XSIZE_HIMETRIC
*pwidth
)
460 ICOM_THIS(OLEPictureImpl
, iface
);
461 TRACE("(%p)->(%p): width is %ld\n", This
, pwidth
, This
->himetricWidth
);
462 *pwidth
= This
->himetricWidth
;
466 /************************************************************************
467 * OLEPictureImpl_get_Height
469 static HRESULT WINAPI
OLEPictureImpl_get_Height(IPicture
*iface
,
470 OLE_YSIZE_HIMETRIC
*pheight
)
472 ICOM_THIS(OLEPictureImpl
, iface
);
473 TRACE("(%p)->(%p): height is %ld\n", This
, pheight
, This
->himetricHeight
);
474 *pheight
= This
->himetricHeight
;
478 /************************************************************************
479 * OLEPictureImpl_Render
481 static HRESULT WINAPI
OLEPictureImpl_Render(IPicture
*iface
, HDC hdc
,
482 long x
, long y
, long cx
, long cy
,
483 OLE_XPOS_HIMETRIC xSrc
,
484 OLE_YPOS_HIMETRIC ySrc
,
485 OLE_XSIZE_HIMETRIC cxSrc
,
486 OLE_YSIZE_HIMETRIC cySrc
,
489 ICOM_THIS(OLEPictureImpl
, iface
);
490 TRACE("(%p)->(%08x, (%ld,%ld), (%ld,%ld) <- (%ld,%ld), (%ld,%ld), %p)\n",
491 This
, hdc
, x
, y
, cx
, cy
, xSrc
, ySrc
, cxSrc
, cySrc
, prcWBounds
);
493 TRACE("prcWBounds (%d,%d) - (%d,%d)\n", prcWBounds
->left
, prcWBounds
->top
,
494 prcWBounds
->right
, prcWBounds
->bottom
);
497 * While the documentation suggests this to be here (or after rendering?)
498 * it does cause an endless recursion in my sample app. -MM 20010804
499 OLEPicture_SendNotify(This,DISPID_PICT_RENDER);
502 switch(This
->desc
.picType
) {
508 /* Set a mapping mode that maps bitmap pixels into HIMETRIC units.
509 NB y-axis gets flipped */
511 hdcBmp
= CreateCompatibleDC(0);
512 SetMapMode(hdcBmp
, MM_ANISOTROPIC
);
513 SetWindowOrgEx(hdcBmp
, 0, 0, NULL
);
514 SetWindowExtEx(hdcBmp
, This
->himetricWidth
, This
->himetricHeight
, NULL
);
515 SetViewportOrgEx(hdcBmp
, 0, This
->origHeight
, NULL
);
516 SetViewportExtEx(hdcBmp
, This
->origWidth
, -This
->origHeight
, NULL
);
518 hbmpOld
= SelectObject(hdcBmp
, This
->desc
.u
.bmp
.hbitmap
);
520 StretchBlt(hdc
, x
, y
, cx
, cy
, hdcBmp
, xSrc
, ySrc
, cxSrc
, cySrc
, SRCCOPY
);
522 SelectObject(hdcBmp
, hbmpOld
);
527 FIXME("Not quite correct implementation of rendering icons...\n");
528 DrawIcon(hdc
,x
,y
,This
->desc
.u
.icon
.hicon
);
531 case PICTYPE_METAFILE
:
532 case PICTYPE_ENHMETAFILE
:
534 FIXME("type %d not implemented\n", This
->desc
.picType
);
540 /************************************************************************
541 * OLEPictureImpl_set_hPal
543 static HRESULT WINAPI
OLEPictureImpl_set_hPal(IPicture
*iface
,
546 ICOM_THIS(OLEPictureImpl
, iface
);
547 FIXME("(%p)->(%08x): stub\n", This
, hpal
);
548 OLEPicture_SendNotify(This
,DISPID_PICT_HPAL
);
552 /************************************************************************
553 * OLEPictureImpl_get_CurDC
555 static HRESULT WINAPI
OLEPictureImpl_get_CurDC(IPicture
*iface
,
558 ICOM_THIS(OLEPictureImpl
, iface
);
559 TRACE("(%p), returning %x\n", This
, This
->hDCCur
);
560 if (phdc
) *phdc
= This
->hDCCur
;
564 /************************************************************************
565 * OLEPictureImpl_SelectPicture
567 static HRESULT WINAPI
OLEPictureImpl_SelectPicture(IPicture
*iface
,
570 OLE_HANDLE
*phbmpOut
)
572 ICOM_THIS(OLEPictureImpl
, iface
);
573 TRACE("(%p)->(%08x, %p, %p)\n", This
, hdcIn
, phdcOut
, phbmpOut
);
574 if (This
->desc
.picType
== PICTYPE_BITMAP
) {
575 SelectObject(hdcIn
,This
->desc
.u
.bmp
.hbitmap
);
578 *phdcOut
= This
->hDCCur
;
579 This
->hDCCur
= hdcIn
;
581 *phbmpOut
= This
->desc
.u
.bmp
.hbitmap
;
584 FIXME("Don't know how to select picture type %d\n",This
->desc
.picType
);
589 /************************************************************************
590 * OLEPictureImpl_get_KeepOriginalFormat
592 static HRESULT WINAPI
OLEPictureImpl_get_KeepOriginalFormat(IPicture
*iface
,
595 ICOM_THIS(OLEPictureImpl
, iface
);
596 TRACE("(%p)->(%p)\n", This
, pfKeep
);
599 *pfKeep
= This
->keepOrigFormat
;
603 /************************************************************************
604 * OLEPictureImpl_put_KeepOriginalFormat
606 static HRESULT WINAPI
OLEPictureImpl_put_KeepOriginalFormat(IPicture
*iface
,
609 ICOM_THIS(OLEPictureImpl
, iface
);
610 TRACE("(%p)->(%d)\n", This
, keep
);
611 This
->keepOrigFormat
= keep
;
612 /* FIXME: what DISPID notification here? */
616 /************************************************************************
617 * OLEPictureImpl_PictureChanged
619 static HRESULT WINAPI
OLEPictureImpl_PictureChanged(IPicture
*iface
)
621 ICOM_THIS(OLEPictureImpl
, iface
);
622 TRACE("(%p)->()\n", This
);
623 OLEPicture_SendNotify(This
,DISPID_PICT_HANDLE
);
627 /************************************************************************
628 * OLEPictureImpl_SaveAsFile
630 static HRESULT WINAPI
OLEPictureImpl_SaveAsFile(IPicture
*iface
,
635 ICOM_THIS(OLEPictureImpl
, iface
);
636 FIXME("(%p)->(%p, %d, %p): stub\n", This
, pstream
, SaveMemCopy
, pcbSize
);
640 /************************************************************************
641 * OLEPictureImpl_get_Attributes
643 static HRESULT WINAPI
OLEPictureImpl_get_Attributes(IPicture
*iface
,
646 ICOM_THIS(OLEPictureImpl
, iface
);
647 TRACE("(%p)->(%p).\n", This
, pdwAttr
);
649 switch (This
->desc
.picType
) {
650 case PICTYPE_BITMAP
: break; /* not 'truely' scalable, see MSDN. */
651 case PICTYPE_ICON
: *pdwAttr
= PICTURE_TRANSPARENT
;break;
652 case PICTYPE_METAFILE
: *pdwAttr
= PICTURE_TRANSPARENT
|PICTURE_SCALABLE
;break;
653 default:FIXME("Unknown pictype %d\n",This
->desc
.picType
);break;
659 /************************************************************************
660 * IConnectionPointContainer
663 static HRESULT WINAPI
OLEPictureImpl_IConnectionPointContainer_QueryInterface(
664 IConnectionPointContainer
* iface
,
668 ICOM_THIS_From_IConnectionPointContainer(IPicture
,iface
);
670 return IPicture_QueryInterface(This
,riid
,ppvoid
);
673 static ULONG WINAPI
OLEPictureImpl_IConnectionPointContainer_AddRef(
674 IConnectionPointContainer
* iface
)
676 ICOM_THIS_From_IConnectionPointContainer(IPicture
, iface
);
678 return IPicture_AddRef(This
);
681 static ULONG WINAPI
OLEPictureImpl_IConnectionPointContainer_Release(
682 IConnectionPointContainer
* iface
)
684 ICOM_THIS_From_IConnectionPointContainer(IPicture
, iface
);
686 return IPicture_Release(This
);
689 static HRESULT WINAPI
OLEPictureImpl_EnumConnectionPoints(
690 IConnectionPointContainer
* iface
,
691 IEnumConnectionPoints
** ppEnum
693 ICOM_THIS_From_IConnectionPointContainer(IPicture
, iface
);
695 FIXME("(%p,%p), stub!\n",This
,ppEnum
);
699 static HRESULT WINAPI
OLEPictureImpl_FindConnectionPoint(
700 IConnectionPointContainer
* iface
,
702 IConnectionPoint
**ppCP
704 ICOM_THIS_From_IConnectionPointContainer(OLEPictureImpl
, iface
);
705 TRACE("(%p,%s,%p)\n",This
,debugstr_guid(riid
),ppCP
);
709 if (IsEqualGUID(riid
,&IID_IPropertyNotifySink
))
710 return IConnectionPoint_QueryInterface(This
->pCP
,&IID_IConnectionPoint
,(LPVOID
)ppCP
);
711 FIXME("tried to find connection point on %s?\n",debugstr_guid(riid
));
714 /************************************************************************
717 /************************************************************************
718 * OLEPictureImpl_IPersistStream_QueryInterface (IUnknown)
720 * See Windows documentation for more details on IUnknown methods.
722 static HRESULT WINAPI
OLEPictureImpl_IPersistStream_QueryInterface(
723 IPersistStream
* iface
,
727 ICOM_THIS_From_IPersistStream(IPicture
, iface
);
729 return IPicture_QueryInterface(This
, riid
, ppvoid
);
732 /************************************************************************
733 * OLEPictureImpl_IPersistStream_AddRef (IUnknown)
735 * See Windows documentation for more details on IUnknown methods.
737 static ULONG WINAPI
OLEPictureImpl_IPersistStream_AddRef(
738 IPersistStream
* iface
)
740 ICOM_THIS_From_IPersistStream(IPicture
, iface
);
742 return IPicture_AddRef(This
);
745 /************************************************************************
746 * OLEPictureImpl_IPersistStream_Release (IUnknown)
748 * See Windows documentation for more details on IUnknown methods.
750 static ULONG WINAPI
OLEPictureImpl_IPersistStream_Release(
751 IPersistStream
* iface
)
753 ICOM_THIS_From_IPersistStream(IPicture
, iface
);
755 return IPicture_Release(This
);
758 /************************************************************************
759 * OLEPictureImpl_IPersistStream_GetClassID
761 static HRESULT WINAPI
OLEPictureImpl_GetClassID(
762 IPersistStream
* iface
,CLSID
* pClassID
)
764 ICOM_THIS_From_IPersistStream(IPicture
, iface
);
765 FIXME("(%p),stub!\n",This
);
769 /************************************************************************
770 * OLEPictureImpl_IPersistStream_IsDirty
772 static HRESULT WINAPI
OLEPictureImpl_IsDirty(
773 IPersistStream
* iface
)
775 ICOM_THIS_From_IPersistStream(IPicture
, iface
);
776 FIXME("(%p),stub!\n",This
);
781 /* for the jpeg decompressor source manager. */
782 static void _jpeg_init_source(j_decompress_ptr cinfo
) { }
784 static boolean
_jpeg_fill_input_buffer(j_decompress_ptr cinfo
) {
785 ERR("(), should not get here.\n");
789 static void _jpeg_skip_input_data(j_decompress_ptr cinfo
,long num_bytes
) {
790 ERR("(%ld), should not get here.\n",num_bytes
);
793 static boolean
_jpeg_resync_to_restart(j_decompress_ptr cinfo
, int desired
) {
794 ERR("(desired=%d), should not get here.\n",desired
);
797 static void _jpeg_term_source(j_decompress_ptr cinfo
) { }
798 #endif /* HAVE_LIBJPEG */
800 /************************************************************************
801 * OLEPictureImpl_IPersistStream_Load (IUnknown)
803 * Loads the binary data from the IStream. Starts at current position.
804 * There appears to be an 2 DWORD header:
808 * Currently implemented: BITMAP, ICON, JPEG.
810 static HRESULT WINAPI
OLEPictureImpl_Load(IPersistStream
* iface
,IStream
*pStm
) {
816 ICOM_THIS_From_IPersistStream(OLEPictureImpl
, iface
);
818 TRACE("(%p,%p)\n",This
,pStm
);
820 hr
=IStream_Read(pStm
,header
,8,&xread
);
821 if (hr
|| xread
!=8) {
822 FIXME("Failure while reading picture header (hr is %lx, nread is %ld).\n",hr
,xread
);
826 xbuf
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,header
[1]);
827 while (xread
< header
[1]) {
829 hr
= IStream_Read(pStm
,xbuf
+xread
,header
[1]-xread
,&nread
);
834 if (xread
!= header
[1])
835 FIXME("Could only read %ld of %ld bytes?\n",xread
,header
[1]);
837 magic
= xbuf
[0] + (xbuf
[1]<<8);
839 case 0xd8ff: { /* JPEG */
841 struct jpeg_decompress_struct jd
;
842 struct jpeg_error_mgr jerr
;
846 BITMAPINFOHEADER bmi
;
849 struct jpeg_source_mgr xjsm
;
851 /* This is basically so we can use in-memory data for jpeg decompression.
852 * We need to have all the functions.
854 xjsm
.next_input_byte
= xbuf
;
855 xjsm
.bytes_in_buffer
= xread
;
856 xjsm
.init_source
= _jpeg_init_source
;
857 xjsm
.fill_input_buffer
= _jpeg_fill_input_buffer
;
858 xjsm
.skip_input_data
= _jpeg_skip_input_data
;
859 xjsm
.resync_to_restart
= _jpeg_resync_to_restart
;
860 xjsm
.term_source
= _jpeg_term_source
;
862 jd
.err
= jpeg_std_error(&jerr
);
863 jpeg_create_decompress(&jd
);
865 ret
=jpeg_read_header(&jd
,TRUE
);
866 jpeg_start_decompress(&jd
);
867 if (ret
!= JPEG_HEADER_OK
) {
868 ERR("Jpeg image in stream has bad format, read header returned %d.\n",ret
);
869 HeapFree(GetProcessHeap(),0,xbuf
);
872 bits
= HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,(jd
.output_height
+1)*jd
.output_width
*jd
.output_components
);
873 samprow
=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY
,jd
.output_width
*jd
.output_components
);
874 while ( jd
.output_scanline
<jd
.output_height
) {
875 x
= jpeg_read_scanlines(&jd
,&samprow
,1);
877 FIXME("failed to read current scanline?\n");
880 memcpy( bits
+jd
.output_scanline
*jd
.output_width
*jd
.output_components
,
882 jd
.output_width
*jd
.output_components
885 bmi
.biSize
= sizeof(bmi
);
886 bmi
.biWidth
= jd
.output_width
;
887 bmi
.biHeight
= -jd
.output_height
;
889 bmi
.biBitCount
= jd
.output_components
<<3;
890 bmi
.biCompression
= BI_RGB
;
891 bmi
.biSizeImage
= jd
.output_height
*jd
.output_width
*jd
.output_components
;
892 bmi
.biXPelsPerMeter
= 0;
893 bmi
.biYPelsPerMeter
= 0;
895 bmi
.biClrImportant
= 0;
897 HeapFree(GetProcessHeap(),0,samprow
);
898 jpeg_finish_decompress(&jd
);
899 jpeg_destroy_decompress(&jd
);
901 This
->desc
.u
.bmp
.hbitmap
=CreateDIBitmap(
910 This
->desc
.picType
= PICTYPE_BITMAP
;
911 OLEPictureImpl_SetBitmap(This
);
913 HeapFree(GetProcessHeap(),0,bits
);
915 ERR("Trying to load JPEG picture, but JPEG supported not compiled in.\n");
920 case 0x4d42: { /* Bitmap */
921 BITMAPFILEHEADER
*bfh
= (BITMAPFILEHEADER
*)xbuf
;
922 BITMAPINFO
*bi
= (BITMAPINFO
*)(bfh
+1);
925 /* Does not matter whether this is a coreheader or not, we only use
926 * components which are in both
929 This
->desc
.u
.bmp
.hbitmap
= CreateDIBitmap(
935 (bi
->bmiHeader
.biBitCount
<=8)?DIB_PAL_COLORS
:DIB_RGB_COLORS
938 This
->desc
.picType
= PICTYPE_BITMAP
;
939 OLEPictureImpl_SetBitmap(This
);
943 case 0x0000: { /* ICON , first word is dwReserved */
945 CURSORICONFILEDIR
*cifd
= (CURSORICONFILEDIR
*)xbuf
;
949 FIXME("icon.idReserved=%d\n",cifd->idReserved);
950 FIXME("icon.idType=%d\n",cifd->idType);
951 FIXME("icon.idCount=%d\n",cifd->idCount);
953 for (i=0;i<cifd->idCount;i++) {
954 FIXME("[%d] width %d\n",i,cifd->idEntries[i].bWidth);
955 FIXME("[%d] height %d\n",i,cifd->idEntries[i].bHeight);
956 FIXME("[%d] bColorCount %d\n",i,cifd->idEntries[i].bColorCount);
957 FIXME("[%d] bReserved %d\n",i,cifd->idEntries[i].bReserved);
958 FIXME("[%d] xHotspot %d\n",i,cifd->idEntries[i].xHotspot);
959 FIXME("[%d] yHotspot %d\n",i,cifd->idEntries[i].yHotspot);
960 FIXME("[%d] dwDIBSize %d\n",i,cifd->idEntries[i].dwDIBSize);
961 FIXME("[%d] dwDIBOffset %d\n",i,cifd->idEntries[i].dwDIBOffset);
965 /* If we have more than one icon, try to find the best.
966 * this currently means '32 pixel wide'.
968 if (cifd
->idCount
!=1) {
969 for (i
=0;i
<cifd
->idCount
;i
++) {
970 if (cifd
->idEntries
[i
].bWidth
== 32)
973 if (i
==cifd
->idCount
) i
=0;
976 hicon
= CreateIconFromResourceEx(
977 xbuf
+cifd
->idEntries
[i
].dwDIBOffset
,
978 cifd
->idEntries
[i
].dwDIBSize
,
981 cifd
->idEntries
[i
].bWidth
,
982 cifd
->idEntries
[i
].bHeight
,
986 FIXME("CreateIcon failed.\n");
989 This
->desc
.picType
= PICTYPE_ICON
;
990 This
->desc
.u
.icon
.hicon
= hicon
;
996 FIXME("Unknown magic %04x\n",magic
);
1000 HeapFree(GetProcessHeap(),0,xbuf
);
1002 /* FIXME: this notify is not really documented */
1004 OLEPicture_SendNotify(This
,DISPID_PICT_TYPE
);
1008 static HRESULT WINAPI
OLEPictureImpl_Save(
1009 IPersistStream
* iface
,IStream
*pStm
,BOOL fClearDirty
)
1011 ICOM_THIS_From_IPersistStream(IPicture
, iface
);
1012 FIXME("(%p,%p,%d),stub!\n",This
,pStm
,fClearDirty
);
1016 static HRESULT WINAPI
OLEPictureImpl_GetSizeMax(
1017 IPersistStream
* iface
,ULARGE_INTEGER
*pcbSize
)
1019 ICOM_THIS_From_IPersistStream(IPicture
, iface
);
1020 FIXME("(%p,%p),stub!\n",This
,pcbSize
);
1024 /************************************************************************
1027 /************************************************************************
1028 * OLEPictureImpl_IDispatch_QueryInterface (IUnknown)
1030 * See Windows documentation for more details on IUnknown methods.
1032 static HRESULT WINAPI
OLEPictureImpl_IDispatch_QueryInterface(
1037 ICOM_THIS_From_IDispatch(IPicture
, iface
);
1039 return IPicture_QueryInterface(This
, riid
, ppvoid
);
1042 /************************************************************************
1043 * OLEPictureImpl_IDispatch_AddRef (IUnknown)
1045 * See Windows documentation for more details on IUnknown methods.
1047 static ULONG WINAPI
OLEPictureImpl_IDispatch_AddRef(
1050 ICOM_THIS_From_IDispatch(IPicture
, iface
);
1052 return IPicture_AddRef(This
);
1055 /************************************************************************
1056 * OLEPictureImpl_IDispatch_Release (IUnknown)
1058 * See Windows documentation for more details on IUnknown methods.
1060 static ULONG WINAPI
OLEPictureImpl_IDispatch_Release(
1063 ICOM_THIS_From_IDispatch(IPicture
, iface
);
1065 return IPicture_Release(This
);
1068 /************************************************************************
1069 * OLEPictureImpl_GetTypeInfoCount (IDispatch)
1071 * See Windows documentation for more details on IDispatch methods.
1073 static HRESULT WINAPI
OLEPictureImpl_GetTypeInfoCount(
1075 unsigned int* pctinfo
)
1082 /************************************************************************
1083 * OLEPictureImpl_GetTypeInfo (IDispatch)
1085 * See Windows documentation for more details on IDispatch methods.
1087 static HRESULT WINAPI
OLEPictureImpl_GetTypeInfo(
1091 ITypeInfo
** ppTInfo
)
1098 /************************************************************************
1099 * OLEPictureImpl_GetIDsOfNames (IDispatch)
1101 * See Windows documentation for more details on IDispatch methods.
1103 static HRESULT WINAPI
OLEPictureImpl_GetIDsOfNames(
1106 LPOLESTR
* rgszNames
,
1116 /************************************************************************
1117 * OLEPictureImpl_Invoke (IDispatch)
1119 * See Windows documentation for more details on IDispatch methods.
1121 static HRESULT WINAPI
OLEPictureImpl_Invoke(
1123 DISPID dispIdMember
,
1127 DISPPARAMS
* pDispParams
,
1128 VARIANT
* pVarResult
,
1129 EXCEPINFO
* pExepInfo
,
1132 FIXME("(dispid: %ld):Stub\n",dispIdMember
);
1134 VariantInit(pVarResult
);
1135 V_VT(pVarResult
) = VT_BOOL
;
1136 V_UNION(pVarResult
,boolVal
) = FALSE
;
1141 static ICOM_VTABLE(IPicture
) OLEPictureImpl_VTable
=
1143 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1144 OLEPictureImpl_QueryInterface
,
1145 OLEPictureImpl_AddRef
,
1146 OLEPictureImpl_Release
,
1147 OLEPictureImpl_get_Handle
,
1148 OLEPictureImpl_get_hPal
,
1149 OLEPictureImpl_get_Type
,
1150 OLEPictureImpl_get_Width
,
1151 OLEPictureImpl_get_Height
,
1152 OLEPictureImpl_Render
,
1153 OLEPictureImpl_set_hPal
,
1154 OLEPictureImpl_get_CurDC
,
1155 OLEPictureImpl_SelectPicture
,
1156 OLEPictureImpl_get_KeepOriginalFormat
,
1157 OLEPictureImpl_put_KeepOriginalFormat
,
1158 OLEPictureImpl_PictureChanged
,
1159 OLEPictureImpl_SaveAsFile
,
1160 OLEPictureImpl_get_Attributes
1163 static ICOM_VTABLE(IDispatch
) OLEPictureImpl_IDispatch_VTable
=
1165 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1166 OLEPictureImpl_IDispatch_QueryInterface
,
1167 OLEPictureImpl_IDispatch_AddRef
,
1168 OLEPictureImpl_IDispatch_Release
,
1169 OLEPictureImpl_GetTypeInfoCount
,
1170 OLEPictureImpl_GetTypeInfo
,
1171 OLEPictureImpl_GetIDsOfNames
,
1172 OLEPictureImpl_Invoke
1175 static ICOM_VTABLE(IPersistStream
) OLEPictureImpl_IPersistStream_VTable
=
1177 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1178 OLEPictureImpl_IPersistStream_QueryInterface
,
1179 OLEPictureImpl_IPersistStream_AddRef
,
1180 OLEPictureImpl_IPersistStream_Release
,
1181 OLEPictureImpl_GetClassID
,
1182 OLEPictureImpl_IsDirty
,
1183 OLEPictureImpl_Load
,
1184 OLEPictureImpl_Save
,
1185 OLEPictureImpl_GetSizeMax
1188 static ICOM_VTABLE(IConnectionPointContainer
) OLEPictureImpl_IConnectionPointContainer_VTable
=
1190 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1191 OLEPictureImpl_IConnectionPointContainer_QueryInterface
,
1192 OLEPictureImpl_IConnectionPointContainer_AddRef
,
1193 OLEPictureImpl_IConnectionPointContainer_Release
,
1194 OLEPictureImpl_EnumConnectionPoints
,
1195 OLEPictureImpl_FindConnectionPoint
1198 /***********************************************************************
1199 * OleCreatePictureIndirect (OLEAUT32.419)
1201 HRESULT WINAPI
OleCreatePictureIndirect(LPPICTDESC lpPictDesc
, REFIID riid
,
1202 BOOL fOwn
, LPVOID
*ppvObj
)
1204 OLEPictureImpl
* newPict
= NULL
;
1207 TRACE("(%p,%p,%d,%p)\n", lpPictDesc
, riid
, fOwn
, ppvObj
);
1218 * Try to construct a new instance of the class.
1220 newPict
= OLEPictureImpl_Construct(lpPictDesc
, fOwn
);
1222 if (newPict
== NULL
)
1223 return E_OUTOFMEMORY
;
1226 * Make sure it supports the interface required by the caller.
1228 hr
= IPicture_QueryInterface((IPicture
*)newPict
, riid
, ppvObj
);
1231 * Release the reference obtained in the constructor. If
1232 * the QueryInterface was unsuccessful, it will free the class.
1234 IPicture_Release((IPicture
*)newPict
);
1240 /***********************************************************************
1241 * OleLoadPicture (OLEAUT32.418)
1243 HRESULT WINAPI
OleLoadPicture( LPSTREAM lpstream
, LONG lSize
, BOOL fRunmode
,
1244 REFIID riid
, LPVOID
*ppvObj
)
1250 TRACE("(%p,%ld,%d,%s,%p), partially implemented.\n",
1251 lpstream
, lSize
, fRunmode
, debugstr_guid(riid
), ppvObj
);
1253 hr
= OleCreatePictureIndirect(NULL
,riid
,!fRunmode
,(LPVOID
*)&newpic
);
1256 hr
= IPicture_QueryInterface(newpic
,&IID_IPersistStream
, (LPVOID
*)&ps
);
1258 FIXME("Could not get IPersistStream iface from Ole Picture?\n");
1259 IPicture_Release(newpic
);
1263 IPersistStream_Load(ps
,lpstream
);
1264 IPersistStream_Release(ps
);
1265 hr
= IPicture_QueryInterface(newpic
,riid
,ppvObj
);
1267 FIXME("Failed to get interface %s from IPicture.\n",debugstr_guid(riid
));
1268 IPicture_Release(newpic
);
1272 /***********************************************************************
1273 * OleLoadPictureEx (OLEAUT32.425)
1275 HRESULT WINAPI
OleLoadPictureEx( LPSTREAM lpstream
, LONG lSize
, BOOL fRunmode
,
1276 REFIID reed
, DWORD xsiz
, DWORD ysiz
, DWORD flags
, LPVOID
*ppvObj
)
1278 FIXME("(%p,%ld,%d,%p,%lx,%lx,%lx,%p), not implemented\n",
1279 lpstream
, lSize
, fRunmode
, reed
, xsiz
, ysiz
, flags
, ppvObj
);