http://bugs.winehq.org/show_bug.cgi?id=16585
--- Comment #10 from Igor Tarasov tarasov.igor@gmail.com 2009-01-04 02:14:34 --- Well, after a lot of digging, I've found the following:
1. Image display is done through OLE IPicture. 2. Real image size is 467 x 338 (for simplicity, let's talk only about the first one). 3. But size that is being passed to PSDRV_StretchDIBits is 12356 x -8942. 4. OLEPictureImpl_Render may render picture to various devices. 5. ...including winex11 and it passes quite the same parameters to BITBLT_InternalStretchBlt. 6. But it does not crash, and works as expected.
The difference between BITBLT_InternalStretchBlt and PSDRV_StretchDIBits in their handling of incoming data is that BITBLT_InternalStretchBlt converts logical coordinates to device coordinates (via LPtoDP) for source coordinates. See http://source.winehq.org/source/dlls/winex11.drv/bitblt.c#L1285
So, the fix seems to be simple: just add LP2DP conversion for source coordinates to PSDRV_StretchDIBits. But there is one problem: LPtoDP requires source device handle, but it does not being passed to PSDRV_StretchDIBits.
Or, possibly, this conversion should be done somewhere here: http://source.winehq.org/source/dlls/gdi32/bitblt.c#L172