- 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); void INTERNAL_CALL BITMAPOBJ_CleanupBitsLock(BITMAPOBJ *pBMObj);
INT FASTCALL BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp); INT FASTCALL BITMAPOBJ_GetWidthBytes (INT bmWidth, INT bpp);
INT FASTCALL BITMAPOBJ_GetRealBitsPixel(INT nBitsPixel);
HBITMAP FASTCALL BITMAPOBJ_CopyBitmap (HBITMAP hBitmap); HBITMAP FASTCALL BITMAPOBJ_CopyBitmap (HBITMAP hBitmap);
INT FASTCALL DIB_GetDIBWidthBytes (INT width, INT depth); INT FASTCALL DIB_GetDIBWidthBytes (INT width, INT depth);
int NTAPI DIB_GetDIBImageBytes (INT width, INT height, INT depth); int NTAPI DIB_GetDIBImageBytes (INT width, INT height, INT depth);

View file

@ -253,6 +253,14 @@ IntCreateCompatibleBitmap(PDC Dc,
INT Width, INT Width,
INT Height); INT Height);
HBITMAP STDCALL
IntGdiCreateBitmap(
INT Width,
INT Height,
UINT Planes,
UINT BitsPixel,
IN OPTIONAL LPBYTE pBits);
HDC STDCALL IntGdiGetDCState(HDC hDC); HDC STDCALL IntGdiGetDCState(HDC hDC);
WORD STDCALL IntGdiSetHookFlags(HDC hDC, WORD Flags); 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 else
{ {
BitmapStretched = NtGdiCreateBitmap(WidthDest, HeightDest, 1, 1, NULL); BitmapStretched = IntGdiCreateBitmap(WidthDest, HeightDest, 1, 1, NULL);
} }
if (NULL == BitmapStretched) if (NULL == BitmapStretched)
{ {

View file

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

View file

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

View file

@ -226,7 +226,7 @@ NtGdiCreateCompatibleDC(HDC hDC)
NewDC->Dc_Attr.szlViewportExt.cy = OrigDC->Dc_Attr.szlViewportExt.cy; NewDC->Dc_Attr.szlViewportExt.cy = OrigDC->Dc_Attr.szlViewportExt.cy;
/* Create default bitmap */ /* 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( OrigDC );
DC_UnlockDc( NewDC ); DC_UnlockDc( NewDC );

View file

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