diff --git a/reactos/subsystems/win32/win32k/include/bitmaps.h b/reactos/subsystems/win32/win32k/include/bitmaps.h index 433392f60df..e8e78b4a74d 100644 --- a/reactos/subsystems/win32/win32k/include/bitmaps.h +++ b/reactos/subsystems/win32/win32k/include/bitmaps.h @@ -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); diff --git a/reactos/subsystems/win32/win32k/include/intgdi.h b/reactos/subsystems/win32/win32k/include/intgdi.h index 180cd870e9c..e93f9ccb699 100644 --- a/reactos/subsystems/win32/win32k/include/intgdi.h +++ b/reactos/subsystems/win32/win32k/include/intgdi.h @@ -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); diff --git a/reactos/subsystems/win32/win32k/ntuser/cursoricon.c b/reactos/subsystems/win32/win32k/ntuser/cursoricon.c index c391709321e..133a14391fd 100644 --- a/reactos/subsystems/win32/win32k/ntuser/cursoricon.c +++ b/reactos/subsystems/win32/win32k/ntuser/cursoricon.c @@ -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) { diff --git a/reactos/subsystems/win32/win32k/objects/bitmaps.c b/reactos/subsystems/win32/win32k/objects/bitmaps.c index dc0df8679c6..93939f3f275 100644 --- a/reactos/subsystems/win32/win32k/objects/bitmaps.c +++ b/reactos/subsystems/win32/win32k/objects/bitmaps.c @@ -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) { diff --git a/reactos/subsystems/win32/win32k/objects/brush.c b/reactos/subsystems/win32/win32k/objects/brush.c index 67e62704d05..698b6f8e9c8 100644 --- a/reactos/subsystems/win32/win32k/objects/brush.c +++ b/reactos/subsystems/win32/win32k/objects/brush.c @@ -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); diff --git a/reactos/subsystems/win32/win32k/objects/dc.c b/reactos/subsystems/win32/win32k/objects/dc.c index 7eb67929155..e51098a8fc4 100644 --- a/reactos/subsystems/win32/win32k/objects/dc.c +++ b/reactos/subsystems/win32/win32k/objects/dc.c @@ -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 ); diff --git a/reactos/subsystems/win32/win32k/objects/pen.c b/reactos/subsystems/win32/win32k/objects/pen.c index 96c7454b831..8271a0d325c 100644 --- a/reactos/subsystems/win32/win32k/objects/pen.c +++ b/reactos/subsystems/win32/win32k/objects/pen.c @@ -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: