- Rename NtGdiCreateBitmap to IntGdiCreateBitmap and remove SEH

- implement new NtGdiCreateBitmap, calling IntGdiCreateBitmap with SEH
- Use only IntGdiCreateBitmap internally
- implement BITMAPOBJ_GetRealBitsPixel, finding an appropriate value for unsupported values of BitsPixel
- make parameter validation more windows compatible

svn path=/trunk/; revision=28341
This commit is contained in:
Timo Kreuzer 2007-08-14 23:22:07 +00:00
parent d91a924361
commit 6f54ba60ab
7 changed files with 90 additions and 36 deletions

View file

@ -39,6 +39,7 @@ BOOL INTERNAL_CALL BITMAPOBJ_InitBitsLock(BITMAPOBJ *pBMObj);
void INTERNAL_CALL BITMAPOBJ_CleanupBitsLock(BITMAPOBJ *pBMObj);
INT FASTCALL BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp);
INT FASTCALL BITMAPOBJ_GetRealBitsPixel(INT nBitsPixel);
HBITMAP FASTCALL BITMAPOBJ_CopyBitmap (HBITMAP hBitmap);
INT FASTCALL DIB_GetDIBWidthBytes (INT width, INT depth);
int NTAPI DIB_GetDIBImageBytes (INT width, INT height, INT depth);

View file

@ -253,6 +253,14 @@ IntCreateCompatibleBitmap(PDC Dc,
INT Width,
INT Height);
HBITMAP STDCALL
IntGdiCreateBitmap(
INT Width,
INT Height,
UINT Planes,
UINT BitsPixel,
IN OPTIONAL LPBYTE pBits);
HDC STDCALL IntGdiGetDCState(HDC hDC);
WORD STDCALL IntGdiSetHookFlags(HDC hDC, WORD Flags);

View file

@ -1308,7 +1308,7 @@ DoStretchBlt(HDC DcDest, int XDest, int YDest, int WidthDest, int HeightDest,
}
else
{
BitmapStretched = NtGdiCreateBitmap(WidthDest, HeightDest, 1, 1, NULL);
BitmapStretched = IntGdiCreateBitmap(WidthDest, HeightDest, 1, 1, NULL);
}
if (NULL == BitmapStretched)
{

View file

@ -32,12 +32,12 @@
)
HBITMAP STDCALL
NtGdiCreateBitmap(
IntGdiCreateBitmap(
INT Width,
INT Height,
UINT Planes,
UINT BitsPixel,
IN OPTIONAL LPBYTE pUnsafeBits)
IN OPTIONAL LPBYTE pBits)
{
PBITMAPOBJ bmp;
HBITMAP hBitmap;
@ -45,32 +45,33 @@ NtGdiCreateBitmap(
LONG WidthBytes;
/* NOTE: Windows also doesn't store nr. of planes separately! */
BitsPixel = BitsPixel * Planes;
WidthBytes = BITMAPOBJ_GetWidthBytes(Width, BitsPixel);
BitsPixel = BITMAPOBJ_GetRealBitsPixel(BitsPixel * Planes);
/* Check parameters */
if (0 == Height || 0 == Width)
if (BitsPixel == 0 || Width < 1 || Height < 1)
{
Size.cx = Size.cy = 1;
}
else
{
Size.cx = abs(Width);
Size.cy = abs(Height);
DPRINT1("Width = %d, Height = %d BitsPixel = %d\n", Width, Height, BitsPixel);
SetLastWin32Error(ERROR_INVALID_PARAMETER);
return 0;
}
WidthBytes = BITMAPOBJ_GetWidthBytes(Width, BitsPixel);
Size.cx = Width;
Size.cy = Height;
/* Create the bitmap object. */
hBitmap = IntCreateBitmap(Size, WidthBytes,
BitmapFormat(BitsPixel, BI_RGB),
(Height < 0 ? BMF_TOPDOWN : 0) |
(NULL == pUnsafeBits ? 0 : BMF_NOZEROINIT), NULL);
(NULL == pBits ? 0 : BMF_NOZEROINIT), NULL);
if (!hBitmap)
{
DPRINT("NtGdiCreateBitmap: returned 0\n");
DPRINT("IntGdiCreateBitmap: returned 0\n");
return 0;
}
DPRINT("NtGdiCreateBitmap:%dx%d, %d BPP colors returning %08x\n",
DPRINT("IntGdiCreateBitmap:%dx%d, %d BPP colors returning %08x\n",
Size.cx, Size.cy, BitsPixel, hBitmap);
bmp = BITMAPOBJ_LockBitmap( hBitmap );
@ -82,17 +83,9 @@ NtGdiCreateBitmap(
bmp->flFlags = BITMAPOBJ_IS_APIBITMAP;
if (NULL != pUnsafeBits)
if (NULL != pBits)
{
_SEH_TRY
{
ProbeForRead(pUnsafeBits, bmp->SurfObj.cjBits, 1);
IntSetBitmapBits(bmp, bmp->SurfObj.cjBits, pUnsafeBits);
}
_SEH_HANDLE
{
}
_SEH_END
IntSetBitmapBits(bmp, bmp->SurfObj.cjBits, pBits);
}
BITMAPOBJ_UnlockBitmap( bmp );
@ -100,6 +93,35 @@ NtGdiCreateBitmap(
return hBitmap;
}
HBITMAP STDCALL
NtGdiCreateBitmap(
INT Width,
INT Height,
UINT Planes,
UINT BitsPixel,
IN OPTIONAL LPBYTE pUnsafeBits)
{
HBITMAP hBitmap;
_SEH_TRY
{
if (pUnsafeBits)
{
UINT cjBits = BITMAPOBJ_GetWidthBytes(Width, BitsPixel) * Height;
ProbeForRead(pUnsafeBits, cjBits, 1);
}
hBitmap = IntGdiCreateBitmap(Width, Height, Planes, BitsPixel, pUnsafeBits);
}
_SEH_HANDLE
{
hBitmap = 0;
}
_SEH_END
return hBitmap;
}
BOOL INTERNAL_CALL
BITMAP_Cleanup(PVOID ObjectBody)
{
@ -152,11 +174,11 @@ IntCreateCompatibleBitmap(
/* 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);
Bmp = IntGdiCreateBitmap (1, 1, 1, 1, NULL);
}
else
{
Bmp = NtGdiCreateBitmap(Width, Height, 1, Dc->w.bitsPerPixel, NULL);
Bmp = IntGdiCreateBitmap(Width, Height, 1, Dc->w.bitsPerPixel, NULL);
}
return Bmp;
@ -272,7 +294,7 @@ NtGdiGetPixel(HDC hDC, INT XPos, INT YPos)
BITMAPINFO bi;
RtlMoveMemory ( &(bi.bmiHeader), &bih, sizeof(bih) );
hBmpTmp = NtGdiCreateDIBitmap ( hDC, &bi.bmiHeader, 0, NULL, &bi, DIB_RGB_COLORS );
//HBITMAP hBmpTmp = NtGdiCreateBitmap ( 1, 1, 1, 32, NULL);
//HBITMAP hBmpTmp = IntGdiCreateBitmap ( 1, 1, 1, 32, NULL);
if ( hBmpTmp )
{
HBITMAP hBmpOld = (HBITMAP)NtGdiSelectObject ( hDCTmp, hBmpTmp );
@ -538,6 +560,29 @@ NtGdiSetPixelV(
/* Internal Functions */
INT FASTCALL
BITMAPOBJ_GetRealBitsPixel(INT nBitsPixel)
{
if (nBitsPixel < 0)
return 0;
if (nBitsPixel <= 1)
return 1;
if (nBitsPixel <= 2)
return 2;
if (nBitsPixel <= 4)
return 4;
if (nBitsPixel <= 8)
return 8;
if (nBitsPixel <= 16)
return 16;
if (nBitsPixel <= 24)
return 24;
if (nBitsPixel <= 32)
return 32;
return 0;
}
INT FASTCALL
BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp)
{

View file

@ -326,7 +326,7 @@ IntGdiCreateDIBBrush(
else
DataPtr += PaletteEntryCount * sizeof(USHORT);
hPattern = NtGdiCreateBitmap(BitmapInfo->bmiHeader.biWidth,
hPattern = IntGdiCreateBitmap(BitmapInfo->bmiHeader.biWidth,
BitmapInfo->bmiHeader.biHeight,
BitmapInfo->bmiHeader.biPlanes,
BitmapInfo->bmiHeader.biBitCount,
@ -378,7 +378,7 @@ IntGdiCreateHatchBrush(
return 0;
}
hPattern = NtGdiCreateBitmap(8, 8, 1, 1, (LPBYTE)HatchBrushes[Style]);
hPattern = IntGdiCreateBitmap(8, 8, 1, 1, (LPBYTE)HatchBrushes[Style]);
if (hPattern == NULL)
{
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);

View file

@ -226,7 +226,7 @@ NtGdiCreateCompatibleDC(HDC hDC)
NewDC->Dc_Attr.szlViewportExt.cy = OrigDC->Dc_Attr.szlViewportExt.cy;
/* Create default bitmap */
if (!(hBitmap = NtGdiCreateBitmap( 1, 1, 1, NewDC->w.bitsPerPixel, NULL )))
if (!(hBitmap = IntGdiCreateBitmap( 1, 1, 1, NewDC->w.bitsPerPixel, NULL )))
{
DC_UnlockDc( OrigDC );
DC_UnlockDc( NewDC );

View file

@ -99,27 +99,27 @@ IntGdiExtCreatePen(
case PS_ALTERNATE:
PenObject->flAttrs |= GDIBRUSH_IS_BITMAP;
PenObject->hbmPattern = NtGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternAlternate);
PenObject->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternAlternate);
break;
case PS_DOT:
PenObject->flAttrs |= GDIBRUSH_IS_BITMAP;
PenObject->hbmPattern = NtGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDot);
PenObject->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDot);
break;
case PS_DASH:
PenObject->flAttrs |= GDIBRUSH_IS_BITMAP;
PenObject->hbmPattern = NtGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDash);
PenObject->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDash);
break;
case PS_DASHDOT:
PenObject->flAttrs |= GDIBRUSH_IS_BITMAP;
PenObject->hbmPattern = NtGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDot);
PenObject->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDot);
break;
case PS_DASHDOTDOT:
PenObject->flAttrs |= GDIBRUSH_IS_BITMAP;
PenObject->hbmPattern = NtGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDotDot);
PenObject->hbmPattern = IntGdiCreateBitmap(24, 1, 1, 1, (LPBYTE)PatternDashDotDot);
break;
case PS_INSIDEFRAME: