LoadImage: respect the desired size when loading a bitmap
Huw D M Davies
h.davies1 at physics.ox.ac.uk
Mon Jun 13 04:50:02 CDT 2005
On Fri, Jun 10, 2005 at 08:24:31PM +0200, Alexandre Julliard wrote:
> Huw D M Davies <h.davies1 at physics.ox.ac.uk> writes:
>
> > + orig_bm = SelectObject(screen_mem_dc, hbitmap);
> > + StretchDIBits(screen_mem_dc, 0, 0, new_width, new_height, 0, 0, width, height, bits, fix_info, DIB_RGB_COLORS, SRCCOPY);
> > + SelectObject(screen_mem_dc, orig_bm);
>
> That's not thread safe, you either need a critical section around the
> global screen_mem_dc, or probably better simply create a mem DC local
> to the function.
Thanks, here's a better version.
Huw Davies <huw at codeweavers.com>
When loading a bitmap we should stretch the image to the
requested size.
--
Huw Davies
huw at codeweavers.com
Index: dlls/user/cursoricon.c
===================================================================
RCS file: /home/wine/wine/dlls/user/cursoricon.c,v
retrieving revision 1.5
diff -u -p -r1.5 cursoricon.c
--- dlls/user/cursoricon.c 25 May 2005 18:42:37 -0000 1.5
+++ dlls/user/cursoricon.c 13 Jun 2005 09:47:39 -0000
@@ -2059,15 +2059,22 @@ static void DIB_FixColorsToLoadflags(BIT
/**********************************************************************
* BITMAP_Load
*/
-static HBITMAP BITMAP_Load( HINSTANCE instance, LPCWSTR name, UINT loadflags )
+static HBITMAP BITMAP_Load( HINSTANCE instance, LPCWSTR name,
+ INT desiredx, INT desiredy, UINT loadflags )
{
- HBITMAP hbitmap = 0;
+ HBITMAP hbitmap = 0, orig_bm;
HRSRC hRsrc;
HGLOBAL handle;
char *ptr = NULL;
- BITMAPINFO *info, *fix_info=NULL;
- HGLOBAL hFix;
+ BITMAPINFO *info, *fix_info = NULL, *scaled_info = NULL;
int size;
+ BYTE pix;
+ char *bits;
+ LONG width, height, new_width, new_height;
+ WORD bpp_dummy;
+ DWORD compr_dummy;
+ INT bm_type;
+ HDC screen_mem_dc = NULL;
if (!(loadflags & LR_LOADFROMFILE))
{
@@ -2090,62 +2097,68 @@ static HBITMAP BITMAP_Load( HINSTANCE in
}
size = bitmap_info_size(info, DIB_RGB_COLORS);
- if ((hFix = GlobalAlloc(0, size))) fix_info=GlobalLock(hFix);
+ fix_info = HeapAlloc(GetProcessHeap(), 0, size);
+ scaled_info = HeapAlloc(GetProcessHeap(), 0, size);
- if (fix_info) {
- BYTE pix;
+ if (!fix_info || !scaled_info) goto end;
+ memcpy(fix_info, info, size);
- memcpy(fix_info, info, size);
- pix = *((LPBYTE)info + size);
- DIB_FixColorsToLoadflags(fix_info, loadflags, pix);
- if (!screen_dc) screen_dc = CreateDCW( DISPLAYW, NULL, NULL, NULL );
+ pix = *((LPBYTE)info + size);
+ DIB_FixColorsToLoadflags(fix_info, loadflags, pix);
- if (screen_dc)
- {
- char *bits = (char *)info + size;
+ memcpy(scaled_info, fix_info, size);
+ bm_type = DIB_GetBitmapInfo( &fix_info->bmiHeader, &width, &height,
+ &bpp_dummy, &compr_dummy);
+ if(desiredx != 0)
+ new_width = desiredx;
+ else
+ new_width = width;
- if (loadflags & LR_CREATEDIBSECTION) {
- DIBSECTION dib;
- fix_info->bmiHeader.biCompression = 0; /* DIBSection can't be compressed */
- hbitmap = CreateDIBSection(screen_dc, fix_info, DIB_RGB_COLORS, NULL, 0, 0);
- GetObjectA(hbitmap, sizeof(DIBSECTION), &dib);
- SetDIBits(screen_dc, hbitmap, 0, dib.dsBm.bmHeight, bits, info,
- DIB_RGB_COLORS);
- }
- else {
- /* If it's possible, create a monochrome bitmap */
-
- LONG width;
- LONG height;
- WORD bpp;
- DWORD compr;
-
- if (DIB_GetBitmapInfo( &fix_info->bmiHeader, &width, &height, &bpp, &compr ) != -1)
- {
- if (width < 0)
- TRACE("Bitmap has a negative width\n");
- else
- {
- /* Top-down DIBs have a negative height */
- if (height < 0) height = -height;
-
- TRACE("width=%ld, height=%ld, bpp=%u, compr=%lu\n", width, height, bpp, compr);
-
- if (is_dib_monochrome(fix_info))
- hbitmap = CreateBitmap(width, height, 1, 1, NULL);
- else
- hbitmap = CreateCompatibleBitmap(screen_dc, width, height);
-
- SetDIBits(screen_dc, hbitmap, 0, height, bits, fix_info, DIB_RGB_COLORS);
- }
- }
- }
- }
+ if(desiredy != 0)
+ new_height = height > 0 ? desiredy : -desiredy;
+ else
+ new_height = height;
- GlobalUnlock(hFix);
- GlobalFree(hFix);
+ if(bm_type == 0)
+ {
+ BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)&scaled_info->bmiHeader;
+ core->bcWidth = new_width;
+ core->bcHeight = new_height;
+ }
+ else
+ {
+ scaled_info->bmiHeader.biWidth = new_width;
+ scaled_info->bmiHeader.biHeight = new_height;
+ }
+
+ if (new_height < 0) new_height = -new_height;
+
+ if (!screen_dc) screen_dc = CreateDCW( DISPLAYW, NULL, NULL, NULL );
+ if (!(screen_mem_dc = CreateCompatibleDC( screen_dc ))) goto end;
+
+ bits = (char *)info + size;
+
+ if (loadflags & LR_CREATEDIBSECTION)
+ {
+ scaled_info->bmiHeader.biCompression = 0; /* DIBSection can't be compressed */
+ hbitmap = CreateDIBSection(screen_dc, scaled_info, DIB_RGB_COLORS, NULL, 0, 0);
+ }
+ else
+ {
+ if (is_dib_monochrome(fix_info))
+ hbitmap = CreateBitmap(new_width, new_height, 1, 1, NULL);
+ else
+ hbitmap = CreateCompatibleBitmap(screen_dc, new_width, new_height);
}
+ orig_bm = SelectObject(screen_mem_dc, hbitmap);
+ StretchDIBits(screen_mem_dc, 0, 0, new_width, new_height, 0, 0, width, height, bits, fix_info, DIB_RGB_COLORS, SRCCOPY);
+ SelectObject(screen_mem_dc, orig_bm);
+
+end:
+ if (screen_mem_dc) DeleteDC(screen_mem_dc);
+ HeapFree(GetProcessHeap(), 0, scaled_info);
+ HeapFree(GetProcessHeap(), 0, fix_info);
if (loadflags & LR_LOADFROMFILE) UnmapViewOfFile( ptr );
return hbitmap;
@@ -2231,7 +2244,7 @@ HANDLE WINAPI LoadImageW( HINSTANCE hins
if (loadflags & LR_LOADFROMFILE) loadflags &= ~LR_SHARED;
switch (type) {
case IMAGE_BITMAP:
- return BITMAP_Load( hinst, name, loadflags );
+ return BITMAP_Load( hinst, name, desiredx, desiredy, loadflags );
case IMAGE_ICON:
if (!screen_dc) screen_dc = CreateDCW( DISPLAYW, NULL, NULL, NULL );
More information about the wine-patches
mailing list