mirror of
https://github.com/reactos/reactos.git
synced 2024-10-22 22:09:47 +00:00
- Handle 1bpp DIBs in NtGdiCreateDIBitmap
- Fix double lock of DC in routines called by NtGdiCreateDIBSection svn path=/trunk/; revision=8757
This commit is contained in:
parent
52f0a740aa
commit
aea7bd7615
|
@ -46,6 +46,8 @@ INT STDCALL BITMAP_GetObject(BITMAPOBJ * bmp, INT count, LPVOID buffer);
|
||||||
BOOL FASTCALL Bitmap_InternalDelete( PBITMAPOBJ pBmp );
|
BOOL FASTCALL Bitmap_InternalDelete( PBITMAPOBJ pBmp );
|
||||||
HBITMAP FASTCALL BitmapToSurf(PBITMAPOBJ BitmapObj, HDEV GDIDevice);
|
HBITMAP FASTCALL BitmapToSurf(PBITMAPOBJ BitmapObj, HDEV GDIDevice);
|
||||||
|
|
||||||
|
HBITMAP FASTCALL IntCreateCompatibleBitmap(PDC Dc, INT Width, INT Height);
|
||||||
|
|
||||||
/* User Entry Points */
|
/* User Entry Points */
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
/* $Id: bitmaps.c,v 1.61 2004/03/14 00:11:28 gvg Exp $ */
|
/* $Id: bitmaps.c,v 1.62 2004/03/15 22:06:55 gvg Exp $ */
|
||||||
#undef WIN32_LEAN_AND_MEAN
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -363,41 +363,56 @@ BOOL FASTCALL Bitmap_InternalDelete( PBITMAPOBJ pBmp )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HBITMAP STDCALL NtGdiCreateCompatibleBitmap(HDC hDC,
|
HBITMAP FASTCALL
|
||||||
|
IntCreateCompatibleBitmap(PDC Dc,
|
||||||
INT Width,
|
INT Width,
|
||||||
INT Height)
|
INT Height)
|
||||||
{
|
{
|
||||||
HBITMAP hbmpRet;
|
HBITMAP Bmp;
|
||||||
PDC dc;
|
|
||||||
|
|
||||||
hbmpRet = 0;
|
Bmp = NULL;
|
||||||
dc = DC_LockDc(hDC);
|
|
||||||
|
if ((Width >= 0x10000) || (Height >= 0x10000))
|
||||||
|
{
|
||||||
|
DPRINT1("got bad width %d or height %d, please look for reason\n", Width, Height);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
|
||||||
|
if (0 == Width || 0 == Height)
|
||||||
|
{
|
||||||
|
Bmp = NtGdiCreateBitmap (1, 1, 1, 1, NULL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Bmp = NtGdiCreateBitmap(Width, Height, 1, Dc->w.bitsPerPixel, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Bmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
HBITMAP STDCALL
|
||||||
|
NtGdiCreateCompatibleBitmap(HDC hDC,
|
||||||
|
INT Width,
|
||||||
|
INT Height)
|
||||||
|
{
|
||||||
|
HBITMAP Bmp;
|
||||||
|
PDC Dc;
|
||||||
|
|
||||||
|
Dc = DC_LockDc(hDC);
|
||||||
|
|
||||||
DPRINT("NtGdiCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n", hDC, Width, Height, dc->w.bitsPerPixel);
|
DPRINT("NtGdiCreateCompatibleBitmap(%04x,%d,%d, bpp:%d) = \n", hDC, Width, Height, dc->w.bitsPerPixel);
|
||||||
|
|
||||||
if (!dc)
|
if (NULL == Dc)
|
||||||
{
|
{
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
if ((Width >= 0x10000) || (Height >= 0x10000))
|
|
||||||
{
|
Bmp = IntCreateCompatibleBitmap(Dc, Width, Height);
|
||||||
DPRINT("got bad width %d or height %d, please look for reason\n", Width, Height);
|
|
||||||
}
|
DPRINT ("\t\t%04x\n", Bmp);
|
||||||
else
|
|
||||||
{
|
|
||||||
/* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
|
|
||||||
if (!Width || !Height)
|
|
||||||
{
|
|
||||||
hbmpRet = NtGdiCreateBitmap (1, 1, 1, 1, NULL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
hbmpRet = NtGdiCreateBitmap(Width, Height, 1, dc->w.bitsPerPixel, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DPRINT ("\t\t%04x\n", hbmpRet);
|
|
||||||
DC_UnlockDc(hDC);
|
DC_UnlockDc(hDC);
|
||||||
return hbmpRet;
|
return Bmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
HBITMAP STDCALL NtGdiCreateBitmapIndirect(CONST BITMAP *BM)
|
HBITMAP STDCALL NtGdiCreateBitmapIndirect(CONST BITMAP *BM)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $Id: dib.c,v 1.42 2004/02/19 21:12:10 weiden Exp $
|
* $Id: dib.c,v 1.43 2004/03/15 22:06:55 gvg Exp $
|
||||||
*
|
*
|
||||||
* ReactOS W32 Subsystem
|
* ReactOS W32 Subsystem
|
||||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
|
||||||
|
@ -87,9 +87,9 @@ UINT STDCALL NtGdiSetDIBColorTable(HDC hDC,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts a DIB to a device-dependent bitmap
|
// Converts a DIB to a device-dependent bitmap
|
||||||
INT STDCALL
|
static INT FASTCALL
|
||||||
NtGdiSetDIBits(
|
IntSetDIBits(
|
||||||
HDC hDC,
|
PDC DC,
|
||||||
HBITMAP hBitmap,
|
HBITMAP hBitmap,
|
||||||
UINT StartScan,
|
UINT StartScan,
|
||||||
UINT ScanLines,
|
UINT ScanLines,
|
||||||
|
@ -97,7 +97,6 @@ NtGdiSetDIBits(
|
||||||
CONST BITMAPINFO *bmi,
|
CONST BITMAPINFO *bmi,
|
||||||
UINT ColorUse)
|
UINT ColorUse)
|
||||||
{
|
{
|
||||||
DC *dc;
|
|
||||||
BITMAPOBJ *bitmap;
|
BITMAPOBJ *bitmap;
|
||||||
HBITMAP SourceBitmap, DestBitmap;
|
HBITMAP SourceBitmap, DestBitmap;
|
||||||
INT result = 0;
|
INT result = 0;
|
||||||
|
@ -116,12 +115,8 @@ NtGdiSetDIBits(
|
||||||
INT scanDirection = 1, DIBWidth;
|
INT scanDirection = 1, DIBWidth;
|
||||||
|
|
||||||
// Check parameters
|
// Check parameters
|
||||||
if (!(dc = DC_LockDc(hDC)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (!(bitmap = BITMAPOBJ_LockBitmap(hBitmap)))
|
if (!(bitmap = BITMAPOBJ_LockBitmap(hBitmap)))
|
||||||
{
|
{
|
||||||
DC_UnlockDc(hDC);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +127,7 @@ NtGdiSetDIBits(
|
||||||
// lpRGB = &bmi->bmiColors[0];
|
// lpRGB = &bmi->bmiColors[0];
|
||||||
|
|
||||||
// Create a temporary surface for the destination bitmap
|
// Create a temporary surface for the destination bitmap
|
||||||
DestBitmap = BitmapToSurf(bitmap, dc->GDIDevice);
|
DestBitmap = BitmapToSurf(bitmap, DC->GDIDevice);
|
||||||
|
|
||||||
DestSurf = (PSURFOBJ) AccessUserObject( (ULONG)DestBitmap );
|
DestSurf = (PSURFOBJ) AccessUserObject( (ULONG)DestBitmap );
|
||||||
DestGDI = (PSURFGDI) AccessInternalObject( (ULONG)DestBitmap );
|
DestGDI = (PSURFGDI) AccessInternalObject( (ULONG)DestBitmap );
|
||||||
|
@ -159,19 +154,18 @@ NtGdiSetDIBits(
|
||||||
SourceSurf = (PSURFOBJ)AccessUserObject((ULONG)SourceBitmap);
|
SourceSurf = (PSURFOBJ)AccessUserObject((ULONG)SourceBitmap);
|
||||||
|
|
||||||
// Destination palette obtained from the hDC
|
// Destination palette obtained from the hDC
|
||||||
hDCPalette = PALETTE_LockPalette(dc->DevInfo->hpalDefault);
|
hDCPalette = PALETTE_LockPalette(DC->DevInfo->hpalDefault);
|
||||||
if (NULL == hDCPalette)
|
if (NULL == hDCPalette)
|
||||||
{
|
{
|
||||||
EngDeleteSurface(SourceBitmap);
|
EngDeleteSurface(SourceBitmap);
|
||||||
EngDeleteSurface(DestBitmap);
|
EngDeleteSurface(DestBitmap);
|
||||||
BITMAPOBJ_UnlockBitmap(hBitmap);
|
BITMAPOBJ_UnlockBitmap(hBitmap);
|
||||||
DC_UnlockDc(hDC);
|
|
||||||
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
DDB_Palette_Type = hDCPalette->Mode;
|
DDB_Palette_Type = hDCPalette->Mode;
|
||||||
DDB_Palette = dc->DevInfo->hpalDefault;
|
DDB_Palette = DC->DevInfo->hpalDefault;
|
||||||
PALETTE_UnlockPalette(dc->DevInfo->hpalDefault);
|
PALETTE_UnlockPalette(DC->DevInfo->hpalDefault);
|
||||||
|
|
||||||
// Source palette obtained from the BITMAPINFO
|
// Source palette obtained from the BITMAPINFO
|
||||||
DIB_Palette = BuildDIBPalette ( (PBITMAPINFO)bmi, (PINT)&DIB_Palette_Type );
|
DIB_Palette = BuildDIBPalette ( (PBITMAPINFO)bmi, (PINT)&DIB_Palette_Type );
|
||||||
|
@ -180,7 +174,6 @@ NtGdiSetDIBits(
|
||||||
EngDeleteSurface(SourceBitmap);
|
EngDeleteSurface(SourceBitmap);
|
||||||
EngDeleteSurface(DestBitmap);
|
EngDeleteSurface(DestBitmap);
|
||||||
BITMAPOBJ_UnlockBitmap(hBitmap);
|
BITMAPOBJ_UnlockBitmap(hBitmap);
|
||||||
DC_UnlockDc(hDC);
|
|
||||||
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
|
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -193,7 +186,6 @@ NtGdiSetDIBits(
|
||||||
EngDeleteSurface(SourceBitmap);
|
EngDeleteSurface(SourceBitmap);
|
||||||
EngDeleteSurface(DestBitmap);
|
EngDeleteSurface(DestBitmap);
|
||||||
BITMAPOBJ_UnlockBitmap(hBitmap);
|
BITMAPOBJ_UnlockBitmap(hBitmap);
|
||||||
DC_UnlockDc(hDC);
|
|
||||||
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
|
SetLastWin32Error(ERROR_NO_SYSTEM_RESOURCES);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -226,11 +218,38 @@ NtGdiSetDIBits(
|
||||||
// WinFree((LPSTR)lpRGB);
|
// WinFree((LPSTR)lpRGB);
|
||||||
|
|
||||||
BITMAPOBJ_UnlockBitmap(hBitmap);
|
BITMAPOBJ_UnlockBitmap(hBitmap);
|
||||||
DC_UnlockDc(hDC);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Converts a DIB to a device-dependent bitmap
|
||||||
|
INT STDCALL
|
||||||
|
NtGdiSetDIBits(
|
||||||
|
HDC hDC,
|
||||||
|
HBITMAP hBitmap,
|
||||||
|
UINT StartScan,
|
||||||
|
UINT ScanLines,
|
||||||
|
CONST VOID *Bits,
|
||||||
|
CONST BITMAPINFO *bmi,
|
||||||
|
UINT ColorUse)
|
||||||
|
{
|
||||||
|
PDC Dc;
|
||||||
|
INT Ret;
|
||||||
|
|
||||||
|
Dc = DC_LockDc(hDC);
|
||||||
|
if (NULL == Dc)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
|
||||||
|
|
||||||
|
DC_UnlockDc(hDC);
|
||||||
|
|
||||||
|
return Ret;
|
||||||
|
}
|
||||||
|
|
||||||
INT STDCALL
|
INT STDCALL
|
||||||
NtGdiSetDIBitsToDevice(
|
NtGdiSetDIBitsToDevice(
|
||||||
HDC hDC,
|
HDC hDC,
|
||||||
|
@ -873,13 +892,13 @@ LONG STDCALL NtGdiGetBitmapBits(HBITMAP hBitmap,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// The CreateDIBitmap function creates a device-dependent bitmap (DDB) from a DIB and, optionally, sets the bitmap bits
|
static HBITMAP FASTCALL
|
||||||
// The DDB that is created will be whatever bit depth your reference DC is
|
IntCreateDIBitmap(PDC Dc, const BITMAPINFOHEADER *header,
|
||||||
HBITMAP STDCALL NtGdiCreateDIBitmap(HDC hdc, const BITMAPINFOHEADER *header,
|
|
||||||
DWORD init, LPCVOID bits, const BITMAPINFO *data,
|
DWORD init, LPCVOID bits, const BITMAPINFO *data,
|
||||||
UINT coloruse)
|
UINT coloruse)
|
||||||
{
|
{
|
||||||
HBITMAP handle;
|
HBITMAP handle;
|
||||||
|
BOOL fColor;
|
||||||
DWORD width;
|
DWORD width;
|
||||||
int height;
|
int height;
|
||||||
WORD bpp;
|
WORD bpp;
|
||||||
|
@ -891,24 +910,88 @@ HBITMAP STDCALL NtGdiCreateDIBitmap(HDC hdc, const BITMAPINFOHEADER *header,
|
||||||
// Check if we should create a monochrome or color bitmap. We create a monochrome bitmap only if it has exactly 2
|
// Check if we should create a monochrome or color bitmap. We create a monochrome bitmap only if it has exactly 2
|
||||||
// colors, which are black followed by white, nothing else. In all other cases, we create a color bitmap.
|
// colors, which are black followed by white, nothing else. In all other cases, we create a color bitmap.
|
||||||
|
|
||||||
// Now create the bitmap
|
if (bpp != 1) fColor = TRUE;
|
||||||
if (init == CBM_INIT)
|
else if ((coloruse != DIB_RGB_COLORS) ||
|
||||||
|
(init != CBM_INIT) || !data) fColor = FALSE;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
handle = NtGdiCreateCompatibleBitmap(hdc, width, height);
|
if (data->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
|
||||||
if (!handle)
|
|
||||||
{
|
{
|
||||||
return 0;
|
RGBQUAD *rgb = data->bmiColors;
|
||||||
|
DWORD col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
|
||||||
|
|
||||||
|
// Check if the first color of the colormap is black
|
||||||
|
if ((col == RGB(0, 0, 0)))
|
||||||
|
{
|
||||||
|
rgb++;
|
||||||
|
col = RGB( rgb->rgbRed, rgb->rgbGreen, rgb->rgbBlue );
|
||||||
|
|
||||||
|
// If the second color is white, create a monochrome bitmap
|
||||||
|
fColor = (col != RGB(0xff,0xff,0xff));
|
||||||
}
|
}
|
||||||
NtGdiSetDIBits(hdc, handle, 0, height, bits, data, coloruse);
|
else fColor = TRUE;
|
||||||
|
}
|
||||||
|
else if (data->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||||
|
{
|
||||||
|
RGBTRIPLE *rgb = ((BITMAPCOREINFO *)data)->bmciColors;
|
||||||
|
DWORD col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue);
|
||||||
|
|
||||||
|
if ((col == RGB(0,0,0)))
|
||||||
|
{
|
||||||
|
rgb++;
|
||||||
|
col = RGB( rgb->rgbtRed, rgb->rgbtGreen, rgb->rgbtBlue );
|
||||||
|
fColor = (col != RGB(0xff,0xff,0xff));
|
||||||
|
}
|
||||||
|
else fColor = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
handle = NtGdiCreateBitmap(width, height, 1, bpp, NULL);
|
DPRINT("(%ld): wrong size for data\n", data->bmiHeader.biSize );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now create the bitmap
|
||||||
|
if (fColor)
|
||||||
|
{
|
||||||
|
handle = IntCreateCompatibleBitmap(Dc, width, height);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
handle = NtGdiCreateBitmap( width, height, 1, 1, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NULL != handle && CBM_INIT == init)
|
||||||
|
{
|
||||||
|
IntSetDIBits(Dc, handle, 0, height, bits, data, coloruse);
|
||||||
}
|
}
|
||||||
|
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The CreateDIBitmap function creates a device-dependent bitmap (DDB) from a DIB and, optionally, sets the bitmap bits
|
||||||
|
// The DDB that is created will be whatever bit depth your reference DC is
|
||||||
|
HBITMAP STDCALL NtGdiCreateDIBitmap(HDC hDc, const BITMAPINFOHEADER *Header,
|
||||||
|
DWORD Init, LPCVOID Bits, const BITMAPINFO *Data,
|
||||||
|
UINT ColorUse)
|
||||||
|
{
|
||||||
|
PDC Dc;
|
||||||
|
HBITMAP Bmp;
|
||||||
|
|
||||||
|
Dc = DC_LockDc(hDc);
|
||||||
|
if (NULL == Dc)
|
||||||
|
{
|
||||||
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bmp = IntCreateDIBitmap(Dc, Header, Init, Bits, Data, ColorUse);
|
||||||
|
|
||||||
|
DC_UnlockDc(hDc);
|
||||||
|
|
||||||
|
return Bmp;
|
||||||
|
}
|
||||||
|
|
||||||
HBITMAP STDCALL NtGdiCreateDIBSection(HDC hDC,
|
HBITMAP STDCALL NtGdiCreateDIBSection(HDC hDC,
|
||||||
CONST BITMAPINFO *bmi,
|
CONST BITMAPINFO *bmi,
|
||||||
UINT Usage,
|
UINT Usage,
|
||||||
|
@ -1036,7 +1119,7 @@ DIB_CreateDIBSection(
|
||||||
// Create Device Dependent Bitmap and add DIB pointer
|
// Create Device Dependent Bitmap and add DIB pointer
|
||||||
if (dib)
|
if (dib)
|
||||||
{
|
{
|
||||||
res = NtGdiCreateDIBitmap(dc->hSelf, bi, 0, NULL, bmi, usage);
|
res = IntCreateDIBitmap(dc, bi, 0, NULL, bmi, usage);
|
||||||
if (! res)
|
if (! res)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Reference in a new issue