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*/
53 DEFAULT_DEBUG_CHANNEL(ole);
55 /*************************************************************************
56 * Declaration of implementation class
59 typedef struct OLEPictureImpl {
62 * IPicture handles IUnknown
65 ICOM_VTABLE(IPicture) *lpvtbl1;
66 ICOM_VTABLE(IDispatch) *lpvtbl2;
67 ICOM_VTABLE(IPersistStream) *lpvtbl3;
68 ICOM_VTABLE(IConnectionPointContainer) *lpvtbl4;
70 /* Object referenece count */
73 /* We own the object and must destroy it ourselves */
76 /* Picture description */
79 /* These are the pixel size of a bitmap */
83 /* And these are the size of the picture converted into HIMETRIC units */
84 OLE_XSIZE_HIMETRIC himetricWidth;
85 OLE_YSIZE_HIMETRIC himetricHeight;
87 IConnectionPoint *pCP;
94 * Macros to retrieve pointer to IUnknown (IPicture) from the other VTables.
96 #define ICOM_THIS_From_IDispatch(impl, name) \
97 impl *This = (impl*)(((char*)name)-sizeof(void*));
98 #define ICOM_THIS_From_IPersistStream(impl, name) \
99 impl *This = (impl*)(((char*)name)-2*sizeof(void*));
100 #define ICOM_THIS_From_IConnectionPointContainer(impl, name) \
101 impl *This = (impl*)(((char*)name)-3*sizeof(void*));
104 * Predeclare VTables. They get initialized at the end.
106 static ICOM_VTABLE(IPicture) OLEPictureImpl_VTable;
107 static ICOM_VTABLE(IDispatch) OLEPictureImpl_IDispatch_VTable;
108 static ICOM_VTABLE(IPersistStream) OLEPictureImpl_IPersistStream_VTable;
109 static ICOM_VTABLE(IConnectionPointContainer) OLEPictureImpl_IConnectionPointContainer_VTable;
111 /***********************************************************************
112 * Implementation of the OLEPictureImpl class.
115 static void OLEPictureImpl_SetBitmap(OLEPictureImpl*This) {
119 TRACE("bitmap handle %08x\n", This->desc.u.bmp.hbitmap);
120 if(GetObjectA(This->desc.u.bmp.hbitmap, sizeof(bm), &bm) != sizeof(bm)) {
121 ERR("GetObject fails\n");
124 This->origWidth = bm.bmWidth;
125 This->origHeight = bm.bmHeight;
126 /* The width and height are stored in HIMETRIC units (0.01 mm),
127 so we take our pixel width divide by pixels per inch and
128 multiply by 25.4 * 100 */
129 /* Should we use GetBitmapDimension if available? */
130 hdcRef = CreateCompatibleDC(0);
131 This->himetricWidth =(bm.bmWidth *2540)/GetDeviceCaps(hdcRef, LOGPIXELSX);
132 This->himetricHeight=(bm.bmHeight*2540)/GetDeviceCaps(hdcRef, LOGPIXELSY);
136 /************************************************************************
137 * OLEPictureImpl_Construct
139 * This method will construct a new instance of the OLEPictureImpl
142 * The caller of this method must release the object when it's
145 static OLEPictureImpl* OLEPictureImpl_Construct(LPPICTDESC pictDesc, BOOL fOwn)
147 OLEPictureImpl* newObject = 0;
150 TRACE("(%p) type = %d\n", pictDesc, pictDesc->picType);
153 * Allocate space for the object.
155 newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(OLEPictureImpl));
161 * Initialize the virtual function table.
163 newObject->lpvtbl1 = &OLEPictureImpl_VTable;
164 newObject->lpvtbl2 = &OLEPictureImpl_IDispatch_VTable;
165 newObject->lpvtbl3 = &OLEPictureImpl_IPersistStream_VTable;
166 newObject->lpvtbl4 = &OLEPictureImpl_IConnectionPointContainer_VTable;
168 CreateConnectionPoint((IUnknown*)newObject,&IID_IPropertyNotifySink,&newObject->pCP);
171 * Start with one reference count. The caller of this function
172 * must release the interface pointer when it is done.
175 newObject->hDCCur = 0;
177 newObject->fOwn = fOwn;
179 /* dunno about original value */
180 newObject->keepOrigFormat = TRUE;
183 if(pictDesc->cbSizeofstruct != sizeof(PICTDESC)) {
184 FIXME("struct size = %d\n", pictDesc->cbSizeofstruct);
186 memcpy(&newObject->desc, pictDesc, sizeof(PICTDESC));
189 switch(pictDesc->picType) {
191 OLEPictureImpl_SetBitmap(newObject);
194 case PICTYPE_METAFILE:
195 TRACE("metafile handle %08x\n", pictDesc->u.wmf.hmeta);
196 newObject->himetricWidth = pictDesc->u.wmf.xExt;
197 newObject->himetricHeight = pictDesc->u.wmf.yExt;
201 case PICTYPE_ENHMETAFILE:
203 FIXME("Unsupported type %d\n", pictDesc->picType);
204 newObject->himetricWidth = newObject->himetricHeight = 0;
208 newObject->desc.picType = PICTYPE_UNINITIALIZED;
211 TRACE("returning %p\n", newObject);
215 /************************************************************************
216 * OLEPictureImpl_Destroy
218 * This method is called by the Release method when the reference
219 * count goes down to 0. It will free all resources used by
221 static void OLEPictureImpl_Destroy(OLEPictureImpl* Obj)
223 TRACE("(%p)\n", Obj);
225 if(Obj->fOwn) { /* We need to destroy the picture */
226 switch(Obj->desc.picType) {
228 DeleteObject(Obj->desc.u.bmp.hbitmap);
230 case PICTYPE_METAFILE:
231 DeleteMetaFile(Obj->desc.u.wmf.hmeta);
234 DestroyIcon(Obj->desc.u.icon.hicon);
236 case PICTYPE_ENHMETAFILE:
237 DeleteEnhMetaFile(Obj->desc.u.emf.hemf);
240 FIXME("Unsupported type %d - unable to delete\n", Obj->desc.picType);
244 HeapFree(GetProcessHeap(), 0, Obj);
247 static ULONG WINAPI OLEPictureImpl_AddRef(IPicture* iface);
249 /************************************************************************
250 * OLEPictureImpl_QueryInterface (IUnknown)
252 * See Windows documentation for more details on IUnknown methods.
254 static HRESULT WINAPI OLEPictureImpl_QueryInterface(
259 ICOM_THIS(OLEPictureImpl, iface);
260 TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppvObject);
263 * Perform a sanity check on the parameters.
265 if ( (This==0) || (ppvObject==0) )
269 * Initialize the return parameter.
274 * Compare the riid with the interface IDs implemented by this object.
276 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
278 *ppvObject = (IPicture*)This;
280 else if (memcmp(&IID_IPicture, riid, sizeof(IID_IPicture)) == 0)
282 *ppvObject = (IPicture*)This;
284 else if (memcmp(&IID_IDispatch, riid, sizeof(IID_IDispatch)) == 0)
286 *ppvObject = (IDispatch*)&(This->lpvtbl2);
288 else if (memcmp(&IID_IPictureDisp, riid, sizeof(IID_IPictureDisp)) == 0)
290 *ppvObject = (IDispatch*)&(This->lpvtbl2);
292 else if (memcmp(&IID_IPersistStream, riid, sizeof(IID_IPersistStream)) == 0)
294 *ppvObject = (IPersistStream*)&(This->lpvtbl3);
296 else if (memcmp(&IID_IConnectionPointContainer, riid, sizeof(IID_IConnectionPointContainer)) == 0)
298 *ppvObject = (IConnectionPointContainer*)&(This->lpvtbl4);
301 * Check that we obtained an interface.
305 FIXME("() : asking for un supported interface %s\n",debugstr_guid(riid));
306 return E_NOINTERFACE;
310 * Query Interface always increases the reference count by one when it is
313 OLEPictureImpl_AddRef((IPicture*)This);
317 /***********************************************************************
318 * OLEPicture_SendNotify (internal)
320 * Sends notification messages of changed properties to any interested
323 static void OLEPicture_SendNotify(OLEPictureImpl* this, DISPID dispID)
325 IEnumConnections *pEnum;
328 if (IConnectionPoint_EnumConnections(this->pCP, &pEnum))
330 while(IEnumConnections_Next(pEnum, 1, &CD, NULL) == S_OK) {
331 IPropertyNotifySink *sink;
333 IUnknown_QueryInterface(CD.pUnk, &IID_IPropertyNotifySink, (LPVOID)&sink);
334 IPropertyNotifySink_OnChanged(sink, dispID);
335 IPropertyNotifySink_Release(sink);
336 IUnknown_Release(CD.pUnk);
338 IEnumConnections_Release(pEnum);
342 /************************************************************************
343 * OLEPictureImpl_AddRef (IUnknown)
345 * See Windows documentation for more details on IUnknown methods.
347 static ULONG WINAPI OLEPictureImpl_AddRef(
350 ICOM_THIS(OLEPictureImpl, iface);
351 TRACE("(%p)->(ref=%ld)\n", This, This->ref);
357 /************************************************************************
358 * OLEPictureImpl_Release (IUnknown)
360 * See Windows documentation for more details on IUnknown methods.
362 static ULONG WINAPI OLEPictureImpl_Release(
365 ICOM_THIS(OLEPictureImpl, iface);
366 TRACE("(%p)->(ref=%ld)\n", This, This->ref);
369 * Decrease the reference count on this object.
374 * If the reference count goes down to 0, perform suicide.
378 OLEPictureImpl_Destroy(This);
387 /************************************************************************
388 * OLEPictureImpl_get_Handle
390 static HRESULT WINAPI OLEPictureImpl_get_Handle(IPicture *iface,
393 ICOM_THIS(OLEPictureImpl, iface);
394 TRACE("(%p)->(%p)\n", This, phandle);
395 switch(This->desc.picType) {
397 *phandle = This->desc.u.bmp.hbitmap;
399 case PICTYPE_METAFILE:
400 *phandle = This->desc.u.wmf.hmeta;
403 *phandle = This->desc.u.icon.hicon;
405 case PICTYPE_ENHMETAFILE:
406 *phandle = This->desc.u.emf.hemf;
409 FIXME("Unimplemented type %d\n", This->desc.picType);
412 TRACE("returning handle %08x\n", *phandle);
416 /************************************************************************
417 * OLEPictureImpl_get_hPal
419 static HRESULT WINAPI OLEPictureImpl_get_hPal(IPicture *iface,
422 ICOM_THIS(OLEPictureImpl, iface);
423 FIXME("(%p)->(%p): stub\n", This, phandle);
427 /************************************************************************
428 * OLEPictureImpl_get_Type
430 static HRESULT WINAPI OLEPictureImpl_get_Type(IPicture *iface,
433 ICOM_THIS(OLEPictureImpl, iface);
434 TRACE("(%p)->(%p): type is %d\n", This, ptype, This->desc.picType);
435 *ptype = This->desc.picType;
439 /************************************************************************
440 * OLEPictureImpl_get_Width
442 static HRESULT WINAPI OLEPictureImpl_get_Width(IPicture *iface,
443 OLE_XSIZE_HIMETRIC *pwidth)
445 ICOM_THIS(OLEPictureImpl, iface);
446 TRACE("(%p)->(%p): width is %ld\n", This, pwidth, This->himetricWidth);
447 *pwidth = This->himetricWidth;
451 /************************************************************************
452 * OLEPictureImpl_get_Height
454 static HRESULT WINAPI OLEPictureImpl_get_Height(IPicture *iface,
455 OLE_YSIZE_HIMETRIC *pheight)
457 ICOM_THIS(OLEPictureImpl, iface);
458 TRACE("(%p)->(%p): height is %ld\n", This, pheight, This->himetricHeight);
459 *pheight = This->himetricHeight;
463 /************************************************************************
464 * OLEPictureImpl_Render
466 static HRESULT WINAPI OLEPictureImpl_Render(IPicture *iface, HDC hdc,
467 long x, long y, long cx, long cy,
468 OLE_XPOS_HIMETRIC xSrc,
469 OLE_YPOS_HIMETRIC ySrc,
470 OLE_XSIZE_HIMETRIC cxSrc,
471 OLE_YSIZE_HIMETRIC cySrc,
474 ICOM_THIS(OLEPictureImpl, iface);
475 TRACE("(%p)->(%08x, (%ld,%ld), (%ld,%ld) <- (%ld,%ld), (%ld,%ld), %p)\n",
476 This, hdc, x, y, cx, cy, xSrc, ySrc, cxSrc, cySrc, prcWBounds);
478 TRACE("prcWBounds (%d,%d) - (%d,%d)\n", prcWBounds->left, prcWBounds->top,
479 prcWBounds->right, prcWBounds->bottom);
482 * While the documentation suggests this to be here (or after rendering?)
483 * it does cause an endless recursion in my sample app. -MM 20010804
484 OLEPicture_SendNotify(This,DISPID_PICT_RENDER);
487 switch(This->desc.picType) {
493 /* Set a mapping mode that maps bitmap pixels into HIMETRIC units.
494 NB y-axis gets flipped */
496 hdcBmp = CreateCompatibleDC(0);
497 SetMapMode(hdcBmp, MM_ANISOTROPIC);
498 SetWindowOrgEx(hdcBmp, 0, 0, NULL);
499 SetWindowExtEx(hdcBmp, This->himetricWidth, This->himetricHeight, NULL);
500 SetViewportOrgEx(hdcBmp, 0, This->origHeight, NULL);
501 SetViewportExtEx(hdcBmp, This->origWidth, -This->origHeight, NULL);
503 hbmpOld = SelectObject(hdcBmp, This->desc.u.bmp.hbitmap);
505 StretchBlt(hdc, x, y, cx, cy, hdcBmp, xSrc, ySrc, cxSrc, cySrc, SRCCOPY);
507 SelectObject(hdcBmp, hbmpOld);
512 FIXME("Not quite correct implementation of rendering icons...\n");
513 DrawIcon(hdc,x,y,This->desc.u.icon.hicon);
516 case PICTYPE_METAFILE:
517 case PICTYPE_ENHMETAFILE:
519 FIXME("type %d not implemented\n", This->desc.picType);
525 /************************************************************************
526 * OLEPictureImpl_set_hPal
528 static HRESULT WINAPI OLEPictureImpl_set_hPal(IPicture *iface,
531 ICOM_THIS(OLEPictureImpl, iface);
532 FIXME("(%p)->(%08x): stub\n", This, hpal);
533 OLEPicture_SendNotify(This,DISPID_PICT_HPAL);
537 /************************************************************************
538 * OLEPictureImpl_get_CurDC
540 static HRESULT WINAPI OLEPictureImpl_get_CurDC(IPicture *iface,
543 ICOM_THIS(OLEPictureImpl, iface);
544 TRACE("(%p), returning %x\n", This, This->hDCCur);
545 if (phdc) *phdc = This->hDCCur;
549 /************************************************************************
550 * OLEPictureImpl_SelectPicture
552 static HRESULT WINAPI OLEPictureImpl_SelectPicture(IPicture *iface,
555 OLE_HANDLE *phbmpOut)
557 ICOM_THIS(OLEPictureImpl, iface);
558 TRACE("(%p)->(%08x, %p, %p)\n", This, hdcIn, phdcOut, phbmpOut);
559 if (This->desc.picType == PICTYPE_BITMAP) {
560 SelectObject(hdcIn,This->desc.u.bmp.hbitmap);
563 *phdcOut = This->hDCCur;
564 This->hDCCur = hdcIn;
566 *phbmpOut = This->desc.u.bmp.hbitmap;
569 FIXME("Don't know how to select picture type %d\n",This->desc.picType);
574 /************************************************************************
575 * OLEPictureImpl_get_KeepOriginalFormat
577 static HRESULT WINAPI OLEPictureImpl_get_KeepOriginalFormat(IPicture *iface,
580 ICOM_THIS(OLEPictureImpl, iface);
581 TRACE("(%p)->(%p)\n", This, pfKeep);
584 *pfKeep = This->keepOrigFormat;
588 /************************************************************************
589 * OLEPictureImpl_put_KeepOriginalFormat
591 static HRESULT WINAPI OLEPictureImpl_put_KeepOriginalFormat(IPicture *iface,
594 ICOM_THIS(OLEPictureImpl, iface);
595 TRACE("(%p)->(%d)\n", This, keep);
596 This->keepOrigFormat = keep;
597 /* FIXME: what DISPID notification here? */
601 /************************************************************************
602 * OLEPictureImpl_PictureChanged
604 static HRESULT WINAPI OLEPictureImpl_PictureChanged(IPicture *iface)
606 ICOM_THIS(OLEPictureImpl, iface);
607 TRACE("(%p)->()\n", This);
608 OLEPicture_SendNotify(This,DISPID_PICT_HANDLE);
612 /************************************************************************
613 * OLEPictureImpl_SaveAsFile
615 static HRESULT WINAPI OLEPictureImpl_SaveAsFile(IPicture *iface,
620 ICOM_THIS(OLEPictureImpl, iface);
621 FIXME("(%p)->(%p, %d, %p): stub\n", This, pstream, SaveMemCopy, pcbSize);
625 /************************************************************************
626 * OLEPictureImpl_get_Attributes
628 static HRESULT WINAPI OLEPictureImpl_get_Attributes(IPicture *iface,
631 ICOM_THIS(OLEPictureImpl, iface);
632 TRACE("(%p)->(%p).\n", This, pdwAttr);
634 switch (This->desc.picType) {
635 case PICTYPE_BITMAP: break; /* not 'truely' scalable, see MSDN. */
636 case PICTYPE_ICON: *pdwAttr = PICTURE_TRANSPARENT;break;
637 case PICTYPE_METAFILE: *pdwAttr = PICTURE_TRANSPARENT|PICTURE_SCALABLE;break;
638 default:FIXME("Unknown pictype %d\n",This->desc.picType);break;
644 /************************************************************************
645 * IConnectionPointContainer
648 static HRESULT WINAPI OLEPictureImpl_IConnectionPointContainer_QueryInterface(
649 IConnectionPointContainer* iface,
653 ICOM_THIS_From_IConnectionPointContainer(IPicture,iface);
655 return IPicture_QueryInterface(This,riid,ppvoid);
658 static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_AddRef(
659 IConnectionPointContainer* iface)
661 ICOM_THIS_From_IConnectionPointContainer(IPicture, iface);
663 return IPicture_AddRef(This);
666 static ULONG WINAPI OLEPictureImpl_IConnectionPointContainer_Release(
667 IConnectionPointContainer* iface)
669 ICOM_THIS_From_IConnectionPointContainer(IPicture, iface);
671 return IPicture_Release(This);
674 static HRESULT WINAPI OLEPictureImpl_EnumConnectionPoints(
675 IConnectionPointContainer* iface,
676 IEnumConnectionPoints** ppEnum
678 ICOM_THIS_From_IConnectionPointContainer(IPicture, iface);
680 FIXME("(%p,%p), stub!\n",This,ppEnum);
684 static HRESULT WINAPI OLEPictureImpl_FindConnectionPoint(
685 IConnectionPointContainer* iface,
687 IConnectionPoint **ppCP
689 ICOM_THIS_From_IConnectionPointContainer(OLEPictureImpl, iface);
690 TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppCP);
694 if (IsEqualGUID(riid,&IID_IPropertyNotifySink))
695 return IConnectionPoint_QueryInterface(This->pCP,&IID_IConnectionPoint,(LPVOID)ppCP);
696 FIXME("tried to find connection point on %s?\n",debugstr_guid(riid));
699 /************************************************************************
702 /************************************************************************
703 * OLEPictureImpl_IPersistStream_QueryInterface (IUnknown)
705 * See Windows documentation for more details on IUnknown methods.
707 static HRESULT WINAPI OLEPictureImpl_IPersistStream_QueryInterface(
708 IPersistStream* iface,
712 ICOM_THIS_From_IPersistStream(IPicture, iface);
714 return IPicture_QueryInterface(This, riid, ppvoid);
717 /************************************************************************
718 * OLEPictureImpl_IPersistStream_AddRef (IUnknown)
720 * See Windows documentation for more details on IUnknown methods.
722 static ULONG WINAPI OLEPictureImpl_IPersistStream_AddRef(
723 IPersistStream* iface)
725 ICOM_THIS_From_IPersistStream(IPicture, iface);
727 return IPicture_AddRef(This);
730 /************************************************************************
731 * OLEPictureImpl_IPersistStream_Release (IUnknown)
733 * See Windows documentation for more details on IUnknown methods.
735 static ULONG WINAPI OLEPictureImpl_IPersistStream_Release(
736 IPersistStream* iface)
738 ICOM_THIS_From_IPersistStream(IPicture, iface);
740 return IPicture_Release(This);
743 /************************************************************************
744 * OLEPictureImpl_IPersistStream_GetClassID
746 static HRESULT WINAPI OLEPictureImpl_GetClassID(
747 IPersistStream* iface,CLSID* pClassID)
749 ICOM_THIS_From_IPersistStream(IPicture, iface);
750 FIXME("(%p),stub!\n",This);
754 /************************************************************************
755 * OLEPictureImpl_IPersistStream_IsDirty
757 static HRESULT WINAPI OLEPictureImpl_IsDirty(
758 IPersistStream* iface)
760 ICOM_THIS_From_IPersistStream(IPicture, iface);
761 FIXME("(%p),stub!\n",This);
766 /* for the jpeg decompressor source manager. */
767 static void _jpeg_init_source(j_decompress_ptr cinfo) { }
769 static boolean _jpeg_fill_input_buffer(j_decompress_ptr cinfo) {
770 ERR("(), should not get here.\n");
774 static void _jpeg_skip_input_data(j_decompress_ptr cinfo,long num_bytes) {
775 ERR("(%ld), should not get here.\n",num_bytes);
778 static boolean _jpeg_resync_to_restart(j_decompress_ptr cinfo, int desired) {
779 ERR("(desired=%d), should not get here.\n",desired);
782 static void _jpeg_term_source(j_decompress_ptr cinfo) { }
783 #endif /* HAVE_LIBJPEG */
785 /************************************************************************
786 * OLEPictureImpl_IPersistStream_Load (IUnknown)
788 * Loads the binary data from the IStream. Starts at current position.
789 * There appears to be an 2 DWORD header:
793 * Currently implemented: BITMAP, ICON, JPEG.
795 static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface,IStream*pStm) {
801 ICOM_THIS_From_IPersistStream(OLEPictureImpl, iface);
803 TRACE("(%p,%p)\n",This,pStm);
805 hr=IStream_Read(pStm,header,8,&xread);
806 if (hr || xread!=8) {
807 FIXME("Failure while reading picture header (hr is %lx, nread is %ld).\n",hr,xread);
811 xbuf = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,header[1]);
812 while (xread < header[1]) {
814 hr = IStream_Read(pStm,xbuf+xread,header[1]-xread,&nread);
819 if (xread != header[1])
820 FIXME("Could only read %ld of %ld bytes?\n",xread,header[1]);
822 magic = xbuf[0] + (xbuf[1]<<8);
824 case 0xd8ff: { /* JPEG */
826 struct jpeg_decompress_struct jd;
827 struct jpeg_error_mgr jerr;
831 BITMAPINFOHEADER bmi;
834 struct jpeg_source_mgr xjsm;
836 /* This is basically so we can use in-memory data for jpeg decompression.
837 * We need to have all the functions.
839 xjsm.next_input_byte = xbuf;
840 xjsm.bytes_in_buffer = xread;
841 xjsm.init_source = _jpeg_init_source;
842 xjsm.fill_input_buffer = _jpeg_fill_input_buffer;
843 xjsm.skip_input_data = _jpeg_skip_input_data;
844 xjsm.resync_to_restart = _jpeg_resync_to_restart;
845 xjsm.term_source = _jpeg_term_source;
847 jd.err = jpeg_std_error(&jerr);
848 jpeg_create_decompress(&jd);
850 ret=jpeg_read_header(&jd,TRUE);
851 jpeg_start_decompress(&jd);
852 if (ret != JPEG_HEADER_OK) {
853 ERR("Jpeg image in stream has bad format, read header returned %d.\n",ret);
854 HeapFree(GetProcessHeap(),0,xbuf);
857 bits = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,(jd.output_height+1)*jd.output_width*jd.output_components);
858 samprow=HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,jd.output_width*jd.output_components);
859 while ( jd.output_scanline<jd.output_height ) {
860 x = jpeg_read_scanlines(&jd,&samprow,1);
862 FIXME("failed to read current scanline?\n");
865 memcpy( bits+jd.output_scanline*jd.output_width*jd.output_components,
867 jd.output_width*jd.output_components
870 bmi.biSize = sizeof(bmi);
871 bmi.biWidth = jd.output_width;
872 bmi.biHeight = -jd.output_height;
874 bmi.biBitCount = jd.output_components<<3;
875 bmi.biCompression = BI_RGB;
876 bmi.biSizeImage = jd.output_height*jd.output_width*jd.output_components;
877 bmi.biXPelsPerMeter = 0;
878 bmi.biYPelsPerMeter = 0;
880 bmi.biClrImportant = 0;
882 HeapFree(GetProcessHeap(),0,samprow);
883 jpeg_finish_decompress(&jd);
884 jpeg_destroy_decompress(&jd);
885 hdcref = CreateCompatibleDC(0);
886 This->desc.u.bmp.hbitmap=CreateDIBitmap(
895 This->desc.picType = PICTYPE_BITMAP;
896 OLEPictureImpl_SetBitmap(This);
898 HeapFree(GetProcessHeap(),0,bits);
900 ERR("Trying to load JPEG picture, but JPEG supported not compiled in.\n");
905 case 0x4d42: { /* Bitmap */
906 BITMAPFILEHEADER *bfh = (BITMAPFILEHEADER*)xbuf;
907 BITMAPINFO *bi = (BITMAPINFO*)(bfh+1);
910 /* Does not matter whether this is a coreheader or not, we only use
911 * components which are in both
913 hdcref = CreateCompatibleDC(0);
914 This->desc.u.bmp.hbitmap = CreateDIBitmap(
920 (bi->bmiHeader.biBitCount<=8)?DIB_PAL_COLORS:DIB_RGB_COLORS
923 This->desc.picType = PICTYPE_BITMAP;
924 OLEPictureImpl_SetBitmap(This);
928 case 0x0000: { /* ICON , first word is dwReserved */
930 CURSORICONFILEDIR *cifd = (CURSORICONFILEDIR*)xbuf;
934 FIXME("icon.idReserved=%d\n",cifd->idReserved);
935 FIXME("icon.idType=%d\n",cifd->idType);
936 FIXME("icon.idCount=%d\n",cifd->idCount);
938 for (i=0;i<cifd->idCount;i++) {
939 FIXME("[%d] width %d\n",i,cifd->idEntries[i].bWidth);
940 FIXME("[%d] height %d\n",i,cifd->idEntries[i].bHeight);
941 FIXME("[%d] bColorCount %d\n",i,cifd->idEntries[i].bColorCount);
942 FIXME("[%d] bReserved %d\n",i,cifd->idEntries[i].bReserved);
943 FIXME("[%d] xHotspot %d\n",i,cifd->idEntries[i].xHotspot);
944 FIXME("[%d] yHotspot %d\n",i,cifd->idEntries[i].yHotspot);
945 FIXME("[%d] dwDIBSize %d\n",i,cifd->idEntries[i].dwDIBSize);
946 FIXME("[%d] dwDIBOffset %d\n",i,cifd->idEntries[i].dwDIBOffset);
950 /* If we have more than one icon, try to find the best.
951 * this currently means '32 pixel wide'.
953 if (cifd->idCount!=1) {
954 for (i=0;i<cifd->idCount;i++) {
955 if (cifd->idEntries[i].bWidth == 32)
958 if (i==cifd->idCount) i=0;
961 hicon = CreateIconFromResourceEx(
962 xbuf+cifd->idEntries[i].dwDIBOffset,
963 cifd->idEntries[i].dwDIBSize,
966 cifd->idEntries[i].bWidth,
967 cifd->idEntries[i].bHeight,
971 FIXME("CreateIcon failed.\n");
974 This->desc.picType = PICTYPE_ICON;
975 This->desc.u.icon.hicon = hicon;
981 FIXME("Unknown magic %04x\n",magic);
985 HeapFree(GetProcessHeap(),0,xbuf);
987 /* FIXME: this notify is not really documented */
989 OLEPicture_SendNotify(This,DISPID_PICT_TYPE);
993 static HRESULT WINAPI OLEPictureImpl_Save(
994 IPersistStream* iface,IStream*pStm,BOOL fClearDirty)
996 ICOM_THIS_From_IPersistStream(IPicture, iface);
997 FIXME("(%p,%p,%d),stub!\n",This,pStm,fClearDirty);
1001 static HRESULT WINAPI OLEPictureImpl_GetSizeMax(
1002 IPersistStream* iface,ULARGE_INTEGER*pcbSize)
1004 ICOM_THIS_From_IPersistStream(IPicture, iface);
1005 FIXME("(%p,%p),stub!\n",This,pcbSize);
1009 /************************************************************************
1012 /************************************************************************
1013 * OLEPictureImpl_IDispatch_QueryInterface (IUnknown)
1015 * See Windows documentation for more details on IUnknown methods.
1017 static HRESULT WINAPI OLEPictureImpl_IDispatch_QueryInterface(
1022 ICOM_THIS_From_IDispatch(IPicture, iface);
1024 return IPicture_QueryInterface(This, riid, ppvoid);
1027 /************************************************************************
1028 * OLEPictureImpl_IDispatch_AddRef (IUnknown)
1030 * See Windows documentation for more details on IUnknown methods.
1032 static ULONG WINAPI OLEPictureImpl_IDispatch_AddRef(
1035 ICOM_THIS_From_IDispatch(IPicture, iface);
1037 return IPicture_AddRef(This);
1040 /************************************************************************
1041 * OLEPictureImpl_IDispatch_Release (IUnknown)
1043 * See Windows documentation for more details on IUnknown methods.
1045 static ULONG WINAPI OLEPictureImpl_IDispatch_Release(
1048 ICOM_THIS_From_IDispatch(IPicture, iface);
1050 return IPicture_Release(This);
1053 /************************************************************************
1054 * OLEPictureImpl_GetTypeInfoCount (IDispatch)
1056 * See Windows documentation for more details on IDispatch methods.
1058 static HRESULT WINAPI OLEPictureImpl_GetTypeInfoCount(
1060 unsigned int* pctinfo)
1067 /************************************************************************
1068 * OLEPictureImpl_GetTypeInfo (IDispatch)
1070 * See Windows documentation for more details on IDispatch methods.
1072 static HRESULT WINAPI OLEPictureImpl_GetTypeInfo(
1076 ITypeInfo** ppTInfo)
1083 /************************************************************************
1084 * OLEPictureImpl_GetIDsOfNames (IDispatch)
1086 * See Windows documentation for more details on IDispatch methods.
1088 static HRESULT WINAPI OLEPictureImpl_GetIDsOfNames(
1091 LPOLESTR* rgszNames,
1101 /************************************************************************
1102 * OLEPictureImpl_Invoke (IDispatch)
1104 * See Windows documentation for more details on IDispatch methods.
1106 static HRESULT WINAPI OLEPictureImpl_Invoke(
1108 DISPID dispIdMember,
1112 DISPPARAMS* pDispParams,
1113 VARIANT* pVarResult,
1114 EXCEPINFO* pExepInfo,
1117 FIXME("(dispid: %ld):Stub\n",dispIdMember);
1119 VariantInit(pVarResult);
1120 pVarResult->vt = VT_BOOL;
1121 pVarResult->u.boolVal = FALSE;
1126 static ICOM_VTABLE(IPicture) OLEPictureImpl_VTable =
1128 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1129 OLEPictureImpl_QueryInterface,
1130 OLEPictureImpl_AddRef,
1131 OLEPictureImpl_Release,
1132 OLEPictureImpl_get_Handle,
1133 OLEPictureImpl_get_hPal,
1134 OLEPictureImpl_get_Type,
1135 OLEPictureImpl_get_Width,
1136 OLEPictureImpl_get_Height,
1137 OLEPictureImpl_Render,
1138 OLEPictureImpl_set_hPal,
1139 OLEPictureImpl_get_CurDC,
1140 OLEPictureImpl_SelectPicture,
1141 OLEPictureImpl_get_KeepOriginalFormat,
1142 OLEPictureImpl_put_KeepOriginalFormat,
1143 OLEPictureImpl_PictureChanged,
1144 OLEPictureImpl_SaveAsFile,
1145 OLEPictureImpl_get_Attributes
1148 static ICOM_VTABLE(IDispatch) OLEPictureImpl_IDispatch_VTable =
1150 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1151 OLEPictureImpl_IDispatch_QueryInterface,
1152 OLEPictureImpl_IDispatch_AddRef,
1153 OLEPictureImpl_IDispatch_Release,
1154 OLEPictureImpl_GetTypeInfoCount,
1155 OLEPictureImpl_GetTypeInfo,
1156 OLEPictureImpl_GetIDsOfNames,
1157 OLEPictureImpl_Invoke
1160 static ICOM_VTABLE(IPersistStream) OLEPictureImpl_IPersistStream_VTable =
1162 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1163 OLEPictureImpl_IPersistStream_QueryInterface,
1164 OLEPictureImpl_IPersistStream_AddRef,
1165 OLEPictureImpl_IPersistStream_Release,
1166 OLEPictureImpl_GetClassID,
1167 OLEPictureImpl_IsDirty,
1168 OLEPictureImpl_Load,
1169 OLEPictureImpl_Save,
1170 OLEPictureImpl_GetSizeMax
1173 static ICOM_VTABLE(IConnectionPointContainer) OLEPictureImpl_IConnectionPointContainer_VTable =
1175 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1176 OLEPictureImpl_IConnectionPointContainer_QueryInterface,
1177 OLEPictureImpl_IConnectionPointContainer_AddRef,
1178 OLEPictureImpl_IConnectionPointContainer_Release,
1179 OLEPictureImpl_EnumConnectionPoints,
1180 OLEPictureImpl_FindConnectionPoint
1183 /***********************************************************************
1184 * OleCreatePictureIndirect (OLEAUT32.419)
1186 HRESULT WINAPI OleCreatePictureIndirect(LPPICTDESC lpPictDesc, REFIID riid,
1187 BOOL fOwn, LPVOID *ppvObj )
1189 OLEPictureImpl* newPict = NULL;
1192 TRACE("(%p,%p,%d,%p)\n", lpPictDesc, riid, fOwn, ppvObj);
1203 * Try to construct a new instance of the class.
1205 newPict = OLEPictureImpl_Construct(lpPictDesc, fOwn);
1207 if (newPict == NULL)
1208 return E_OUTOFMEMORY;
1211 * Make sure it supports the interface required by the caller.
1213 hr = IPicture_QueryInterface((IPicture*)newPict, riid, ppvObj);
1216 * Release the reference obtained in the constructor. If
1217 * the QueryInterface was unsuccessful, it will free the class.
1219 IPicture_Release((IPicture*)newPict);
1225 /***********************************************************************
1226 * OleLoadPicture (OLEAUT32.418)
1228 HRESULT WINAPI OleLoadPicture( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
1229 REFIID riid, LPVOID *ppvObj )
1235 TRACE("(%p,%ld,%d,%s,%p), partially implemented.\n",
1236 lpstream, lSize, fRunmode, debugstr_guid(riid), ppvObj);
1238 hr = OleCreatePictureIndirect(NULL,riid,!fRunmode,(LPVOID*)&newpic);
1241 hr = IPicture_QueryInterface(newpic,&IID_IPersistStream, (LPVOID*)&ps);
1243 FIXME("Could not get IPersistStream iface from Ole Picture?\n");
1244 IPicture_Release(newpic);
1248 IPersistStream_Load(ps,lpstream);
1249 IPersistStream_Release(ps);
1250 hr = IPicture_QueryInterface(newpic,riid,ppvObj);
1252 FIXME("Failed to get interface %s from IPicture.\n",debugstr_guid(riid));
1253 IPicture_Release(newpic);
1257 /***********************************************************************
1258 * OleLoadPictureEx (OLEAUT32.425)
1260 HRESULT WINAPI OleLoadPictureEx( LPSTREAM lpstream, LONG lSize, BOOL fRunmode,
1261 REFIID reed, DWORD xsiz, DWORD ysiz, DWORD flags, LPVOID *ppvObj )
1263 FIXME("(%p,%ld,%d,%p,%lx,%lx,%lx,%p), not implemented\n",
1264 lpstream, lSize, fRunmode, reed, xsiz, ysiz, flags, ppvObj);