4 * Implementation of OLE IPicture and related interfaces
6 * Copyright 2000 Huw D M Davies for CodeWeavers.
7 * Copyright 2001 Marcus Meissner
12 * Support PICTYPE_BITMAP and PICTYPE_ICON, altough only bitmaps very well..
13 * Lots of methods are just stubs.
16 * NOTES (or things that msdn doesn't tell you)
18 * The width and height properties are returned in HIMETRIC units (0.01mm)
19 * IPicture::Render also uses these to select a region of the src picture.
20 * A bitmap's size is converted into these units by using the screen resolution
21 * thus an 8x8 bitmap on a 96dpi screen has a size of 212x212 (8/96 * 2540).
37 #include "wine/obj_picture.h"
38 #include "wine/obj_connection.h"
40 #include "debugtools.h"
42 #include "wine/wingdi16.h"
43 #include "cursoricon.h"
46 /* This is a hack, so jpeglib.h does not redefine INT32 and the like*/
48 #define UINT16 JPEG_UINT16
55 DEFAULT_DEBUG_CHANNEL(ole);
57 /*************************************************************************
58 * Declaration of implementation class
61 typedef struct OLEPictureImpl {
64 * IPicture handles IUnknown
67 ICOM_VTABLE(IPicture) *lpvtbl1;
68 ICOM_VTABLE(IDispatch) *lpvtbl2;
69 ICOM_VTABLE(IPersistStream) *lpvtbl3;
70 ICOM_VTABLE(IConnectionPointContainer) *lpvtbl4;
72 /* Object referenece count */
75 /* We own the object and must destroy it ourselves */
78 /* Picture description */
81 /* These are the pixel size of a bitmap */
85 /* And these are the size of the picture converted into HIMETRIC units */
86 OLE_XSIZE_HIMETRIC himetricWidth;
87 OLE_YSIZE_HIMETRIC himetricHeight;
89 IConnectionPoint *pCP;
96 * Macros to retrieve pointer to IUnknown (IPicture) from the other VTables.
98 #define ICOM_THIS_From_IDispatch(impl, name) \
99 impl *This = (impl*)(((char*)name)-sizeof(void*));
100 #define ICOM_THIS_From_IPersistStream(impl, name) \
101 impl *This = (impl*)(((char*)name)-2*sizeof(void*));
102 #define ICOM_THIS_From_IConnectionPointContainer(impl, name) \
103 impl *This = (impl*)(((char*)name)-3*sizeof(void*));
106 * Predeclare VTables. They get initialized at the end.
108 static ICOM_VTABLE(IPicture) OLEPictureImpl_VTable;
109 static ICOM_VTABLE(IDispatch) OLEPictureImpl_IDispatch_VTable;
110 static ICOM_VTABLE(IPersistStream) OLEPictureImpl_IPersistStream_VTable;
111 static ICOM_VTABLE(IConnectionPointContainer) OLEPictureImpl_IConnectionPointContainer_VTable;
113 /***********************************************************************
114 * Implementation of the OLEPictureImpl class.
117 static void OLEPictureImpl_SetBitmap(OLEPictureImpl*This) {
121 TRACE("bitmap handle %08x\n", This->desc.u.bmp.hbitmap);
122 if(GetObjectA(This->desc.u.bmp.hbitmap, sizeof(bm), &bm) != sizeof(bm)) {
123 ERR("GetObject fails\n");
126 This->origWidth = bm.bmWidth;
127 This->origHeight = bm.bmHeight;
128 /* The width and height are stored in HIMETRIC units (0.01 mm),
129 so we take our pixel width divide by pixels per inch and
130 multiply by 25.4 * 100 */
131 /* Should we use GetBitmapDimension if available? */
132 hdcRef = CreateCompatibleDC(0);
133 This->himetricWidth =(bm.bmWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX);
134 This->himetricHeight=(bm.bmHeight*2540)/GetDeviceCaps(hdcRef, LOGPIXELSY);
138 /************************************************************************
139 * OLEPictureImpl_Construct
141 * This method will construct a new instance of the OLEPictureImpl
144 * The caller of this method must release the object when it's
147 static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn)
149 OLEPictureImpl* newObject = 0;
152 TRACE("(%p) type = %d\n", pictDesc, pictDesc->picType);
155 * Allocate space for the object.
157 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEPictureImpl));
163 * Initialize the virtual function table.
165 newObject->lpvtbl1 = &OLEPictureImpl_VTable;
166 newObject->lpvtbl2 = &OLEPictureImpl_IDispatch_VTable;
167 newObject->lpvtbl3 = &OLEPictureImpl_IPersistStream_VTable;
168 newObject->lpvtbl4 = &OLEPictureImpl_IConnectionPointContainer_VTable;
170 CreateConnectionPoint((IUnknown*)newObject,&IID_IPropertyNotifySink,&newObject->pCP);
173 * Start with one reference count. The caller of this function
174 * must release the interface pointer when it is done.
177 newObject->hDCCur = 0;
179 newObject->fOwn = fOwn;
181 /* dunno about original value */
182 newObject->keepOrigFormat = TRUE;
185 if(pictDesc->cbSizeofstruct != sizeof(PICTDESC)) {
186 FIXME("struct size = %d\n", pictDesc->cbSizeofstruct);
188 memcpy(&newObject->desc, pictDesc, sizeof(PICTDESC));
191 switch(pictDesc->picType) {
193 OLEPictureImpl_SetBitmap(newObject);
196 case PICTYPE_METAFILE:
197 TRACE("metafile handle %08x\n", pictDesc->u.wmf.hmeta);
198 newObject->himetricWidth = pictDesc->u.wmf.xExt;
199 newObject->himetricHeight = pictDesc->u.wmf.yExt;
203 case PICTYPE_ENHMETAFILE:
205 FIXME("Unsupported type %d\n", pictDesc->picType);
206 newObject->himetricWidth = newObject->himetricHeight = 0;
210 newObject->desc.picType = PICTYPE_UNINITIALIZED;
213 TRACE("returning %p\n", newObject);
217 /************************************************************************
218 * OLEPictureImpl_Destroy
220 * This method is called by the Release method when the reference
221 * count goes down to 0. It will free all resources used by
223 static void OLEPictureImpl_Destroy(OLEPictureImpl* Obj)
225 TRACE("(%p)\n", Obj);
227 if(Obj->fOwn) { /* We need to destroy the picture */
228 switch(Obj->desc.picType) {
230 DeleteObject(Obj->desc.u.bmp.hbitmap);
232 case PICTYPE_METAFILE:
233 DeleteMetaFile(Obj->desc.u.wmf.hmeta);
236 DestroyIcon(Obj->desc.u.icon.hicon);
238 case PICTYPE_ENHMETAFILE:
239 DeleteEnhMetaFile(Obj->desc.u.emf.hemf);
242 FIXME("Unsupported type %d - unable to delete\n", Obj->desc.picType);
246 HeapFree(GetProcessHeap(), 0, Obj);
249 static ULONG WINAPI OLEPictureImpl_AddRef(IPicture* iface);
251 /************************************************************************
252 * OLEPictureImpl_QueryInterface (IUnknown)
254 * See Windows documentation for more details on IUnknown methods.
256 static HRESULT WINAPI OLEPictureImpl_QueryInterface(
261 ICOM_THIS(OLEPictureImpl, iface);
262 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject);
265 * Perform a sanity check on the parameters.
267 if ( (This==0) || (ppvObject==0) )
271 * Initialize the return parameter.
276 * Compare the riid with the interface IDs implemented by this object.
278 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
280 *ppvObject = (IPicture*)This;
282 else if (memcmp(&IID_IPicture, riid, sizeof(IID_IPicture)) == 0)
284 *ppvObject = (IPicture*)This;
286 else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0)
288 *ppvObject = (IDispatch*)&(This->lpvtbl2);
290 else if (memcmp(&IID_IPictureDisp, riid, sizeof(IID_IPictureDisp)) == 0)
292 *ppvObject = (IDispatch*)&(This->lpvtbl2);
294 else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
296 *ppvObject = (IPersistStream*)&(This->lpvtbl3);
298 else if (memcmp(&IID_IConnectionPointContainer, riid, sizeof(IID_IConnectionPointContainer)) == 0)
300 *ppvObject = (IConnectionPointContainer*)&(This->lpvtbl4);
303 * Check that we obtained an interface.
307 FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid));
308 return E_NOINTERFACE;
312 * Query Interface always increases the reference count by one when it is
315 OLEPictureImpl_AddRef((IPicture*)This);
319 /***********************************************************************
320 * OLEPicture_SendNotify (internal)
322 * Sends notification messages of changed properties to any interested
325 static void OLEPicture_SendNotify(OLEPictureImpl* this, DISPID dispID)
327 IEnumConnections *pEnum;
330 if (IConnectionPoint_EnumConnections(this->pCP, &pEnum))
332 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
333 IPropertyNotifySink *sink;
335 IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
336 IPropertyNotifySink_OnChanged(sink, dispID);
337 IPropertyNotifySink_Release(sink);
338 IUnknown_Release(CD.pUnk);
340 IEnumConnections_Release(pEnum);
344 /************************************************************************
345 * OLEPictureImpl_AddRef (IUnknown)
347 * See Windows documentation for more details on IUnknown methods.
349 static ULONG WINAPI OLEPictureImpl_AddRef(
352 ICOM_THIS(OLEPictureImpl, iface);
353 TRACE("(%p)->(ref=%ld)\n", This, This->ref);
359 /************************************************************************
360 * OLEPictureImpl_Release (IUnknown)
362 * See Windows documentation for more details on IUnknown methods.
364 static ULONG WINAPI OLEPictureImpl_Release(
367 ICOM_THIS(OLEPictureImpl, iface);
368 TRACE("(%p)->(ref=%ld)\n", This, This->ref);
371 * Decrease the reference count on this object.
376 * If the reference count goes down to 0, perform suicide.
380 OLEPictureImpl_Destroy(This);
389 /************************************************************************
390 * OLEPictureImpl_get_Handle
392 static HRESULT WINAPI OLEPictureImpl_get_Handle(IPicture *iface,
395 ICOM_THIS(OLEPictureImpl, iface);
396 TRACE("(%p)->(%p)\n", This, phandle);
397 switch(This->desc.picType) {
399 *phandle = This->desc.u.bmp.hbitmap;
401 case PICTYPE_METAFILE:
402 *phandle = This->desc.u.wmf.hmeta;
405 *phandle = This->desc.u.icon.hicon;
407 case PICTYPE_ENHMETAFILE:
408 *phandle = This->desc.u.emf.hemf;
411 FIXME("Unimplemented type %d\n", This->desc.picType);
414 TRACE("returning handle %08x\n", *phandle);
418 /************************************************************************
419 * OLEPictureImpl_get_hPal
421 static HRESULT WINAPI OLEPictureImpl_get_hPal(IPicture *iface,
424 ICOM_THIS(OLEPictureImpl, iface);
425 FIXME("(%p)->(%p): stub\n", This, phandle);
429 /************************************************************************
430 * OLEPictureImpl_get_Type
432 static HRESULT WINAPI OLEPictureImpl_get_Type(IPicture *iface,
435 ICOM_THIS(OLEPictureImpl, iface);
436 TRACE("(%p)->(%p): type is %d\n", This, ptype, This->desc.picType);
437 *ptype = This->desc.picType;
441 /************************************************************************
442 * OLEPictureImpl_get_Width
444 static HRESULT WINAPI OLEPictureImpl_get_Width(IPicture *iface,
445 OLE_XSIZE_HIMETRIC *pwidth)
447 ICOM_THIS(OLEPictureImpl, iface);
448 TRACE("(%p)->(%p): width is %ld\n", This, pwidth, This->himetricWidth);
449 *pwidth = This->himetricWidth;
453 /************************************************************************
454 * OLEPictureImpl_get_Height
456 static HRESULT WINAPI OLEPictureImpl_get_Height(IPicture *iface,
457 OLE_YSIZE_HIMETRIC *pheight)
459 ICOM_THIS(OLEPictureImpl, iface);
460 TRACE("(%p)->(%p): height is %ld\n", This, pheight, This->himetricHeight);
461 *pheight = This->himetricHeight;
465 /************************************************************************
466 * OLEPictureImpl_Render
468 static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc,
469 long x, long y, long cx, long cy,
470 OLE_XPOS_HIMETRIC xSrc,
471 OLE_YPOS_HIMETRIC ySrc,
472 OLE_XSIZE_HIMETRIC cxSrc,
473 OLE_YSIZE_HIMETRIC cySrc,
476 ICOM_THIS(OLEPictureImpl, iface);
477 TRACE("(%p)->(%08x, (%ld,%ld), (%ld,%ld) <- (%ld,%ld), (%ld,%ld), %p)\n",
478 This, hdc, x, y, cx, cy, xSrc, ySrc, cxSrc, cySrc, prcWBounds);
480 TRACE("prcWBounds (%d,%d) - (%d,%d)\n", prcWBounds->left, prcWBounds->top,
481 prcWBounds->right, prcWBounds->bottom);
484 * While the documentation suggests this to be here (or after rendering?)
485 * it does cause an endless recursion in my sample app. -MM 20010804
486 OLEPicture_SendNotify(This,DISPID_PICT_RENDER);
489 switch(This->desc.picType) {
495 /* Set a mapping mode that maps bitmap pixels into HIMETRIC units.
496 NB y-axis gets flipped */
498 hdcBmp = CreateCompatibleDC(0);
499 SetMapMode(hdcBmp, MM_ANISOTROPIC);
500 SetWindowOrgEx(hdcBmp, 0, 0, NULL);
501 SetWindowExtEx(hdcBmp, This->himetricWidth, This->himetricHeight, NULL);
502 SetViewportOrgEx(hdcBmp, 0, This->origHeight, NULL);
503 SetViewportExtEx(hdcBmp, This->origWidth, -This->origHeight, NULL);
505 hbmpOld = SelectObject(hdcBmp, This->desc.u.bmp.hbitmap);
507 StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCCOPY);
509 SelectObject(hdcBmp, hbmpOld);
514 FIXME("Not quite correct implementation of rendering icons...\n");
515 DrawIcon(hdc,x,y,This->desc.u.icon.hicon);
518 case PICTYPE_METAFILE:
519 case PICTYPE_ENHMETAFILE:
521 FIXME("type %d not implemented\n", This->desc.picType);
527 /************************************************************************
528 * OLEPictureImpl_set_hPal
530 static HRESULT WINAPI OLEPictureImpl_set_hPal(IPicture *iface,
533 ICOM_THIS(OLEPictureImpl, iface);
534 FIXME("(%p)->(%08x): stub\n", This, hpal);
535 OLEPicture_SendNotify(This,DISPID_PICT_HPAL);
539 /************************************************************************
540 * OLEPictureImpl_get_CurDC
542 static HRESULT WINAPI OLEPictureImpl_get_CurDC(IPicture *iface,
545 ICOM_THIS(OLEPictureImpl, iface);
546 TRACE("(%p), returning %x\n", This, This->hDCCur);
547 if (phdc) *phdc = This->hDCCur;
551 /************************************************************************
552 * OLEPictureImpl_SelectPicture
554 static HRESULT WINAPI OLEPictureImpl_SelectPicture(IPicture *iface,
557 OLE_HANDLE *phbmpOut)
559 ICOM_THIS(OLEPictureImpl, iface);
560 TRACE("(%p)->(%08x, %p, %p)\n", This, hdcIn, phdcOut, phbmpOut);
561 if (This->desc.picType == PICTYPE_BITMAP) {
562 SelectObject(hdcIn,This->desc.u.bmp.hbitmap);
565 *phdcOut = This->hDCCur;
566 This->hDCCur = hdcIn;
568 *phbmpOut = This->desc.u.bmp.hbitmap;
571 FIXME("Don't know how to select picture type %d\n",This->desc.picType);
576 /************************************************************************
577 * OLEPictureImpl_get_KeepOriginalFormat
579 static HRESULT WINAPI OLEPictureImpl_get_KeepOriginalFormat(IPicture *iface,
582 ICOM_THIS(OLEPictureImpl, iface);
583 TRACE("(%p)->(%p)\n", This, pfKeep);
586 *pfKeep = This->keepOrigFormat;
590 /************************************************************************
591 * OLEPictureImpl_put_KeepOriginalFormat
593 static HRESULT WINAPI OLEPictureImpl_put_KeepOriginalFormat(IPicture *iface,
596 ICOM_THIS(OLEPictureImpl, iface);
597 TRACE("(%p)->(%d)\n", This, keep);
598 This->keepOrigFormat = keep;
599 /* FIXME: what DISPID notification here? */
603 /************************************************************************
604 * OLEPictureImpl_PictureChanged
606 static HRESULT WINAPI OLEPictureImpl_PictureChanged(IPicture *iface)
608 ICOM_THIS(OLEPictureImpl, iface);
609 TRACE("(%p)->()\n", This);
610 OLEPicture_SendNotify(This,DISPID_PICT_HANDLE);
614 /************************************************************************
615 * OLEPictureImpl_SaveAsFile
617 static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface,
622 ICOM_THIS(OLEPictureImpl, iface);
623 FIXME("(%p)->(%p, %d, %p): stub\n", This, pstream, SaveMemCopy, pcbSize);
627 /************************************************************************
628 * OLEPictureImpl_get_Attributes
630 static HRESULT WINAPI OLEPictureImpl_get_Attributes(IPicture *iface,
633 ICOM_THIS(OLEPictureImpl, iface);
634 TRACE("(%p)->(%p).\n", This, pdwAttr);
636 switch (This->desc.picType) {
637 case PICTYPE_BITMAP: break; /* not 'truely' scalable, see MSDN. */
638 case PICTYPE_ICON: *pdwAttr = PICTURE_TRANSPARENT;break;
639 case PICTYPE_METAFILE: *pdwAttr = PICTURE_TRANSPARENT|PICTURE_SCALABLE;break;
640 default:FIXME("Unknown pictype %d\n",This->desc.picType);break;
646 /************************************************************************
647 * IConnectionPointContainer
650 static HRESULT WINAPI OLEPictureImpl_IConnectionPointContainer_QueryInterface(
651 IConnectionPointContainer* iface,
655 ICOM_THIS_From_IConnectionPointContainer(IPicture,iface);
657 return IPicture_QueryInterface(This,riid,ppvoid);
660 static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_AddRef(
661 IConnectionPointContainer* iface)
663 ICOM_THIS_From_IConnectionPointContainer(IPicture, iface);
665 return IPicture_AddRef(This);
668 static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_Release(
669 IConnectionPointContainer* iface)
671 ICOM_THIS_From_IConnectionPointContainer(IPicture, iface);
673 return IPicture_Release(This);
676 static HRESULT WINAPI OLEPictureImpl_EnumConnectionPoints(
677 IConnectionPointContainer* iface,
678 IEnumConnectionPoints** ppEnum
680 ICOM_THIS_From_IConnectionPointContainer(IPicture, iface);
682 FIXME("(%p,%p), stub!\n",This,ppEnum);
686 static HRESULT WINAPI OLEPictureImpl_FindConnectionPoint(
687 IConnectionPointContainer* iface,
689 IConnectionPoint **ppCP
691 ICOM_THIS_From_IConnectionPointContainer(OLEPictureImpl, iface);
692 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppCP);
696 if (IsEqualGUID(riid,&IID_IPropertyNotifySink))
697 return IConnectionPoint_QueryInterface(This->pCP,&IID_IConnectionPoint,(LPVOID)ppCP);
698 FIXME("tried to find connection point on %s?\n",debugstr_guid(riid));
701 /************************************************************************
704 /************************************************************************
705 * OLEPictureImpl_IPersistStream_QueryInterface (IUnknown)
707 * See Windows documentation for more details on IUnknown methods.
709 static HRESULT WINAPI OLEPictureImpl_IPersistStream_QueryInterface(
710 IPersistStream* iface,
714 ICOM_THIS_From_IPersistStream(IPicture, iface);
716 return IPicture_QueryInterface(This, riid, ppvoid);
719 /************************************************************************
720 * OLEPictureImpl_IPersistStream_AddRef (IUnknown)
722 * See Windows documentation for more details on IUnknown methods.
724 static ULONG WINAPI OLEPictureImpl_IPersistStream_AddRef(
725 IPersistStream* iface)
727 ICOM_THIS_From_IPersistStream(IPicture, iface);
729 return IPicture_AddRef(This);
732 /************************************************************************
733 * OLEPictureImpl_IPersistStream_Release (IUnknown)
735 * See Windows documentation for more details on IUnknown methods.
737 static ULONG WINAPI OLEPictureImpl_IPersistStream_Release(
738 IPersistStream* iface)
740 ICOM_THIS_From_IPersistStream(IPicture, iface);
742 return IPicture_Release(This);
745 /************************************************************************
746 * OLEPictureImpl_IPersistStream_GetClassID
748 static HRESULT WINAPI OLEPictureImpl_GetClassID(
749 IPersistStream* iface,CLSID* pClassID)
751 ICOM_THIS_From_IPersistStream(IPicture, iface);
752 FIXME("(%p),stub!\n",This);
756 /************************************************************************
757 * OLEPictureImpl_IPersistStream_IsDirty
759 static HRESULT WINAPI OLEPictureImpl_IsDirty(
760 IPersistStream* iface)
762 ICOM_THIS_From_IPersistStream(IPicture, iface);
763 FIXME("(%p),stub!\n",This);
768 /* for the jpeg decompressor source manager. */
769 static void _jpeg_init_source(j_decompress_ptr cinfo) { }
771 static boolean _jpeg_fill_input_buffer(j_decompress_ptr cinfo) {
772 ERR("(), should not get here.\n");
776 static void _jpeg_skip_input_data(j_decompress_ptr cinfo,long num_bytes) {
777 ERR("(%ld), should not get here.\n",num_bytes);
780 static boolean _jpeg_resync_to_restart(j_decompress_ptr cinfo, int desired) {
781 ERR("(desired=%d), should not get here.\n",desired);
784 static void _jpeg_term_source(j_decompress_ptr cinfo) { }
785 #endif /* HAVE_LIBJPEG */
787 /************************************************************************
788 * OLEPictureImpl_IPersistStream_Load (IUnknown)
790 * Loads the binary data from the IStream. Starts at current position.
791 * There appears to be an 2 DWORD header:
795 * Currently implemented: BITMAP, ICON, JPEG.
797 static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
803 ICOM_THIS_From_IPersistStream(OLEPictureImpl, iface);
805 TRACE("(%p,%p)\n",This,pStm);
807 hr=IStream_Read(pStm,header,8,&xread);
808 if (hr || xread!=8) {
809 FIXME("Failure while reading picture header (hr is %lx, nread is %ld).\n",hr,xread);
813 xbuf = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,header[1]);
814 while (xread < header[1]) {
816 hr = IStream_Read(pStm,xbuf+xread,header[1]-xread,&nread);
821 if (xread != header[1])
822 FIXME("Could only read %ld of %ld bytes?\n",xread,header[1]);
824 magic = xbuf[0] + (xbuf[1]<<8);
826 case 0xd8ff: { /* JPEG */
828 struct jpeg_decompress_struct jd;
829 struct jpeg_error_mgr jerr;
833 BITMAPINFOHEADER bmi;
836 struct jpeg_source_mgr xjsm;
838 /* This is basically so we can use in-memory data for jpeg decompression.
839 * We need to have all the functions.
841 xjsm.next_input_byte = xbuf;
842 xjsm.bytes_in_buffer = xread;
843 xjsm.init_source = _jpeg_init_source;
844 xjsm.fill_input_buffer = _jpeg_fill_input_buffer;
845 xjsm.skip_input_data = _jpeg_skip_input_data;
846 xjsm.resync_to_restart = _jpeg_resync_to_restart;
847 xjsm.term_source = _jpeg_term_source;
849 jd.err = jpeg_std_error(&jerr);
850 jpeg_create_decompress(&jd);
852 ret=jpeg_read_header(&jd,TRUE);
853 jpeg_start_decompress(&jd);
854 if (ret != JPEG_HEADER_OK) {
855 ERR("Jpeg image in stream has bad format, read header returned %d.\n",ret);
856 HeapFree(GetProcessHeap(),0,xbuf);
859 bits = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(jd.output_height+1)*jd.output_width*jd.output_components);
860 samprow=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,jd.output_width*jd.output_components);
861 while ( jd.output_scanline<jd.output_height ) {
862 x = jpeg_read_scanlines(&jd,&samprow,1);
864 FIXME("failed to read current scanline?\n");
867 memcpy( bits+jd.output_scanline*jd.output_width*jd.output_components,
869 jd.output_width*jd.output_components
872 bmi.biSize = sizeof(bmi);
873 bmi.biWidth = jd.output_width;
874 bmi.biHeight = -jd.output_height;
876 bmi.biBitCount = jd.output_components<<3;
877 bmi.biCompression = BI_RGB;
878 bmi.biSizeImage = jd.output_height*jd.output_width*jd.output_components;
879 bmi.biXPelsPerMeter = 0;
880 bmi.biYPelsPerMeter = 0;
882 bmi.biClrImportant = 0;
884 HeapFree(GetProcessHeap(),0,samprow);
885 jpeg_finish_decompress(&jd);
886 jpeg_destroy_decompress(&jd);
888 This->desc.u.bmp.hbitmap=CreateDIBitmap(
897 This->desc.picType = PICTYPE_BITMAP;
898 OLEPictureImpl_SetBitmap(This);
900 HeapFree(GetProcessHeap(),0,bits);
902 ERR("Trying to load JPEG picture, but JPEG supported not compiled in.\n");
907 case 0x4d42: { /* Bitmap */
908 BITMAPFILEHEADER *bfh = (BITMAPFILEHEADER*)xbuf;
909 BITMAPINFO *bi = (BITMAPINFO*)(bfh+1);
912 /* Does not matter whether this is a coreheader or not, we only use
913 * components which are in both
916 This->desc.u.bmp.hbitmap = CreateDIBitmap(
922 (bi->bmiHeader.biBitCount<=8)?DIB_PAL_COLORS:DIB_RGB_COLORS
925 This->desc.picType = PICTYPE_BITMAP;
926 OLEPictureImpl_SetBitmap(This);
930 case 0x0000: { /* ICON , first word is dwReserved */
932 CURSORICONFILEDIR *cifd = (CURSORICONFILEDIR*)xbuf;
936 FIXME("icon.idReserved=%d\n",cifd->idReserved);
937 FIXME("icon.idType=%d\n",cifd->idType);
938 FIXME("icon.idCount=%d\n",cifd->idCount);
940 for (i=0;i<cifd->idCount;i++) {
941 FIXME("[%d] width %d\n",i,cifd->idEntries[i].bWidth);
942 FIXME("[%d] height %d\n",i,cifd->idEntries[i].bHeight);
943 FIXME("[%d] bColorCount %d\n",i,cifd->idEntries[i].bColorCount);
944 FIXME("[%d] bReserved %d\n",i,cifd->idEntries[i].bReserved);
945 FIXME("[%d] xHotspot %d\n",i,cifd->idEntries[i].xHotspot);
946 FIXME("[%d] yHotspot %d\n",i,cifd->idEntries[i].yHotspot);
947 FIXME("[%d] dwDIBSize %d\n",i,cifd->idEntries[i].dwDIBSize);
948 FIXME("[%d] dwDIBOffset %d\n",i,cifd->idEntries[i].dwDIBOffset);
952 /* If we have more than one icon, try to find the best.
953 * this currently means '32 pixel wide'.
955 if (cifd->idCount!=1) {
956 for (i=0;i<cifd->idCount;i++) {
957 if (cifd->idEntries[i].bWidth == 32)
960 if (i==cifd->idCount) i=0;
963 hicon = CreateIconFromResourceEx(
964 xbuf+cifd->idEntries[i].dwDIBOffset,
965 cifd->idEntries[i].dwDIBSize,
968 cifd->idEntries[i].bWidth,
969 cifd->idEntries[i].bHeight,
973 FIXME("CreateIcon failed.\n");
976 This->desc.picType = PICTYPE_ICON;
977 This->desc.u.icon.hicon = hicon;
983 FIXME("Unknown magic %04x\n",magic);
987 HeapFree(GetProcessHeap(),0,xbuf);
989 /* FIXME: this notify is not really documented */
991 OLEPicture_SendNotify(This,DISPID_PICT_TYPE);
995 static HRESULT WINAPI OLEPictureImpl_Save(
996 IPersistStream* iface,IStream*pStm,BOOL fClearDirty)
998 ICOM_THIS_From_IPersistStream(IPicture, iface);
999 FIXME("(%p,%p,%d),stub!\n",This,pStm,fClearDirty);
1003 static HRESULT WINAPI OLEPictureImpl_GetSizeMax(
1004 IPersistStream* iface,ULARGE_INTEGER*pcbSize)
1006 ICOM_THIS_From_IPersistStream(IPicture, iface);
1007 FIXME("(%p,%p),stub!\n",This,pcbSize);
1011 /************************************************************************
1014 /************************************************************************
1015 * OLEPictureImpl_IDispatch_QueryInterface (IUnknown)
1017 * See Windows documentation for more details on IUnknown methods.
1019 static HRESULT WINAPI OLEPictureImpl_IDispatch_QueryInterface(
1024 ICOM_THIS_From_IDispatch(IPicture, iface);
1026 return IPicture_QueryInterface(This, riid, ppvoid);
1029 /************************************************************************
1030 * OLEPictureImpl_IDispatch_AddRef (IUnknown)
1032 * See Windows documentation for more details on IUnknown methods.
1034 static ULONG WINAPI OLEPictureImpl_IDispatch_AddRef(
1037 ICOM_THIS_From_IDispatch(IPicture, iface);
1039 return IPicture_AddRef(This);
1042 /************************************************************************
1043 * OLEPictureImpl_IDispatch_Release (IUnknown)
1045 * See Windows documentation for more details on IUnknown methods.
1047 static ULONG WINAPI OLEPictureImpl_IDispatch_Release(
1050 ICOM_THIS_From_IDispatch(IPicture, iface);
1052 return IPicture_Release(This);
1055 /************************************************************************
1056 * OLEPictureImpl_GetTypeInfoCount (IDispatch)
1058 * See Windows documentation for more details on IDispatch methods.
1060 static HRESULT WINAPI OLEPictureImpl_GetTypeInfoCount(
1062 unsigned int* pctinfo)
1069 /************************************************************************
1070 * OLEPictureImpl_GetTypeInfo (IDispatch)
1072 * See Windows documentation for more details on IDispatch methods.
1074 static HRESULT WINAPI OLEPictureImpl_GetTypeInfo(
1078 ITypeInfo** ppTInfo)
1085 /************************************************************************
1086 * OLEPictureImpl_GetIDsOfNames (IDispatch)
1088 * See Windows documentation for more details on IDispatch methods.
1090 static HRESULT WINAPI OLEPictureImpl_GetIDsOfNames(
1093 LPOLESTR* rgszNames,
1103 /************************************************************************
1104 * OLEPictureImpl_Invoke (IDispatch)
1106 * See Windows documentation for more details on IDispatch methods.
1108 static HRESULT WINAPI OLEPictureImpl_Invoke(
1110 DISPID dispIdMember,
1114 DISPPARAMS* pDispParams,
1115 VARIANT* pVarResult,
1116 EXCEPINFO* pExepInfo,
1119 FIXME("(dispid: %ld):Stub\n",dispIdMember);
1121 VariantInit(pVarResult);
1122 V_VT(pVarResult) = VT_BOOL;
1123 V_UNION(pVarResult,boolVal) = FALSE;
1128 static ICOM_VTABLE(IPicture) OLEPictureImpl_VTable =
1130 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1131 OLEPictureImpl_QueryInterface,
1132 OLEPictureImpl_AddRef,
1133 OLEPictureImpl_Release,
1134 OLEPictureImpl_get_Handle,
1135 OLEPictureImpl_get_hPal,
1136 OLEPictureImpl_get_Type,
1137 OLEPictureImpl_get_Width,
1138 OLEPictureImpl_get_Height,
1139 OLEPictureImpl_Render,
1140 OLEPictureImpl_set_hPal,
1141 OLEPictureImpl_get_CurDC,
1142 OLEPictureImpl_SelectPicture,
1143 OLEPictureImpl_get_KeepOriginalFormat,
1144 OLEPictureImpl_put_KeepOriginalFormat,
1145 OLEPictureImpl_PictureChanged,
1146 OLEPictureImpl_SaveAsFile,
1147 OLEPictureImpl_get_Attributes
1150 static ICOM_VTABLE(IDispatch) OLEPictureImpl_IDispatch_VTable =
1152 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1153 OLEPictureImpl_IDispatch_QueryInterface,
1154 OLEPictureImpl_IDispatch_AddRef,
1155 OLEPictureImpl_IDispatch_Release,
1156 OLEPictureImpl_GetTypeInfoCount,
1157 OLEPictureImpl_GetTypeInfo,
1158 OLEPictureImpl_GetIDsOfNames,
1159 OLEPictureImpl_Invoke
1162 static ICOM_VTABLE(IPersistStream) OLEPictureImpl_IPersistStream_VTable =
1164 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1165 OLEPictureImpl_IPersistStream_QueryInterface,
1166 OLEPictureImpl_IPersistStream_AddRef,
1167 OLEPictureImpl_IPersistStream_Release,
1168 OLEPictureImpl_GetClassID,
1169 OLEPictureImpl_IsDirty,
1170 OLEPictureImpl_Load,
1171 OLEPictureImpl_Save,
1172 OLEPictureImpl_GetSizeMax
1175 static ICOM_VTABLE(IConnectionPointContainer) OLEPictureImpl_IConnectionPointContainer_VTable =
1177 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1178 OLEPictureImpl_IConnectionPointContainer_QueryInterface,
1179 OLEPictureImpl_IConnectionPointContainer_AddRef,
1180 OLEPictureImpl_IConnectionPointContainer_Release,
1181 OLEPictureImpl_EnumConnectionPoints,
1182 OLEPictureImpl_FindConnectionPoint
1185 /***********************************************************************
1186 * OleCreatePictureIndirect (OLEAUT32.419)
1188 HRESULT WINAPI OleCreatePictureIndirect(LPPICTDESC lpPictDesc, REFIID riid,
1189 BOOL fOwn, LPVOID *ppvObj )
1191 OLEPictureImpl* newPict = NULL;
1194 TRACE("(%p,%p,%d,%p)\n", lpPictDesc, riid, fOwn, ppvObj);
1205 * Try to construct a new instance of the class.
1207 newPict = OLEPictureImpl_Construct(lpPictDesc, fOwn);
1209 if (newPict == NULL)
1210 return E_OUTOFMEMORY;
1213 * Make sure it supports the interface required by the caller.
1215 hr = IPicture_QueryInterface((IPicture*)newPict, riid, ppvObj);
1218 * Release the reference obtained in the constructor. If
1219 * the QueryInterface was unsuccessful, it will free the class.
1221 IPicture_Release((IPicture*)newPict);
1227 /***********************************************************************
1228 * OleLoadPicture (OLEAUT32.418)
1230 HRESULT WINAPI OleLoadPicture( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
1231 REFIID riid, LPVOID *ppvObj )
1237 TRACE("(%p,%ld,%d,%s,%p), partially implemented.\n",
1238 lpstream, lSize, fRunmode, debugstr_guid(riid), ppvObj);
1240 hr = OleCreatePictureIndirect(NULL,riid,!fRunmode,(LPVOID*)&newpic);
1243 hr = IPicture_QueryInterface(newpic,&IID_IPersistStream, (LPVOID*)&ps);
1245 FIXME("Could not get IPersistStream iface from Ole Picture?\n");
1246 IPicture_Release(newpic);
1250 IPersistStream_Load(ps,lpstream);
1251 IPersistStream_Release(ps);
1252 hr = IPicture_QueryInterface(newpic,riid,ppvObj);
1254 FIXME("Failed to get interface %s from IPicture.\n",debugstr_guid(riid));
1255 IPicture_Release(newpic);
1259 /***********************************************************************
1260 * OleLoadPictureEx (OLEAUT32.425)
1262 HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
1263 REFIID reed, DWORD xsiz, DWORD ysiz, DWORD flags, LPVOID *ppvObj )
1265 FIXME("(%p,%ld,%d,%p,%lx,%lx,%lx,%p), not implemented\n",
1266 lpstream, lSize, fRunmode, reed, xsiz, ysiz, flags, ppvObj);