diff --git a/reactos/subsystems/win32/win32k/eng/surface.c b/reactos/subsystems/win32/win32k/eng/surface.c index 622b99da2d5..6493671a6d8 100644 --- a/reactos/subsystems/win32/win32k/eng/surface.c +++ b/reactos/subsystems/win32/win32k/eng/surface.c @@ -37,28 +37,19 @@ gajBitsPerFormat[11] = }; -ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression) +ULONG FASTCALL BitmapFormat(ULONG cBits, ULONG iCompression) { - switch (Compression) + switch (iCompression) { case BI_RGB: /* Fall through */ case BI_BITFIELDS: - switch (Bits) - { - case 1: - return BMF_1BPP; - case 4: - return BMF_4BPP; - case 8: - return BMF_8BPP; - case 16: - return BMF_16BPP; - case 24: - return BMF_24BPP; - case 32: - return BMF_32BPP; - } + if (cBits <= 1) return BMF_1BPP; + if (cBits <= 4) return BMF_4BPP; + if (cBits <= 8) return BMF_8BPP; + if (cBits <= 16) return BMF_16BPP; + if (cBits <= 24) return BMF_24BPP; + if (cBits <= 32) return BMF_32BPP; return 0; case BI_RLE4: diff --git a/reactos/subsystems/win32/win32k/include/bitmaps.h b/reactos/subsystems/win32/win32k/include/bitmaps.h index 802028d4afa..7310766ff99 100644 --- a/reactos/subsystems/win32/win32k/include/bitmaps.h +++ b/reactos/subsystems/win32/win32k/include/bitmaps.h @@ -11,7 +11,6 @@ typedef struct tagBITMAPV5INFO INT APIENTRY BITMAP_GetObject(SURFACE * bmp, INT count, LPVOID buffer); HBITMAP FASTCALL IntCreateBitmap(IN SIZEL Size, IN LONG Width, IN ULONG Format, IN ULONG Flags, IN PVOID Bits); HBITMAP FASTCALL BITMAP_CopyBitmap (HBITMAP hBitmap); -UINT FASTCALL BITMAP_GetRealBitsPixel(UINT nBitsPixel); HBITMAP APIENTRY diff --git a/reactos/subsystems/win32/win32k/include/surface.h b/reactos/subsystems/win32/win32k/include/surface.h index 485f3dc72b3..26e512d9c29 100644 --- a/reactos/subsystems/win32/win32k/include/surface.h +++ b/reactos/subsystems/win32/win32k/include/surface.h @@ -125,7 +125,7 @@ SURFACE_bSetBitmapBits( #define GDIDEV(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev)) #define GDIDEVFUNCS(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))->DriverFunctions -ULONG FASTCALL BitmapFormat (WORD Bits, DWORD Compression); +ULONG FASTCALL BitmapFormat(ULONG cBits, ULONG iCompression); extern UCHAR gajBitsPerFormat[]; #define BitsPerFormat(Format) gajBitsPerFormat[Format] diff --git a/reactos/subsystems/win32/win32k/objects/bitmaps.c b/reactos/subsystems/win32/win32k/objects/bitmaps.c index 573101fcf5e..2fe310af5a0 100644 --- a/reactos/subsystems/win32/win32k/objects/bitmaps.c +++ b/reactos/subsystems/win32/win32k/objects/bitmaps.c @@ -161,60 +161,47 @@ NtGdiCreateBitmap( IN OPTIONAL LPBYTE pUnsafeBits) { HBITMAP hbmp; - ULONG cjWidthBytes, iFormat; + ULONG cRealBpp, cjWidthBytes, iFormat; + ULONGLONG cjSize; - /* NOTE: Windows also doesn't store nr. of planes separately! */ - cBitsPixel = BITMAP_GetRealBitsPixel(cBitsPixel * cPlanes); + /* Calculate bitmap format and real bits per pixel. */ + iFormat = BitmapFormat(cBitsPixel * cPlanes, BI_RGB); + cRealBpp = gajBitsPerFormat[iFormat]; - /* Calculate bitmap format */ - iFormat = BitmapFormat(cBitsPixel, BI_RGB); + /* Calculate width and image size in bytes */ + cjWidthBytes = WIDTH_BYTES_ALIGN16(nWidth, cRealBpp); + cjSize = cjWidthBytes * nHeight; - /* Check parameters */ - if (iFormat == 0 || nWidth <= 0 || nHeight <= 0) + /* Check parameters (possible overflow of cjWidthBytes!) */ + if (iFormat == 0 || nWidth <= 0 || nWidth >= 0x8000000 || nHeight <= 0 || + cBitsPixel > 32 || cPlanes > 32 || cjSize >= 0x100000000ULL) { - DPRINT1("Width = %d, Height = %d BitsPixel = %d\n", - nWidth, nHeight, cBitsPixel); + DPRINT1("Invalid bitmap format! Width=%d, Height=%d, Bpp=%d, Planes=%d\n", + nWidth, nHeight, cBitsPixel, cPlanes); EngSetLastError(ERROR_INVALID_PARAMETER); return NULL; } - if(WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel)*nHeight >= 0x8000000) - { - /* I just can't get enough, I just can't get enough */ - EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); - return NULL; - } + /* Call internal function. */ + hbmp = GreCreateBitmapEx(nWidth, nHeight, 0, iFormat, 0, 0, NULL, DDB_SURFACE); - /* Make sure that cjBits will not overflow */ - cjWidthBytes = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel); - if ((ULONGLONG)cjWidthBytes * nHeight >= 0x100000000ULL) + if (pUnsafeBits && hbmp) { - DPRINT1("Width = %d, Height = %d BitsPixel = %d\n", - nWidth, nHeight, cBitsPixel); - EngSetLastError(ERROR_INVALID_PARAMETER); - return NULL; - } - - /* cBitsPixel = cBitsPixel * cPlanes now! */ - hbmp = GreCreateBitmap(nWidth, nHeight, 1, cBitsPixel, NULL); - - if (pUnsafeBits) - { - PSURFACE psurf = SURFACE_LockSurface(hbmp); + PSURFACE psurf = SURFACE_LockSurface(hbmp); _SEH2_TRY { - ProbeForRead(pUnsafeBits, cjWidthBytes * nHeight, 1); + ProbeForRead(pUnsafeBits, cjSize, 1); UnsafeSetBitmapBits(psurf, 0, pUnsafeBits); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { - SURFACE_UnlockSurface(psurf); + SURFACE_UnlockSurface(psurf); SURFACE_FreeSurfaceByHandle(hbmp); _SEH2_YIELD(return NULL;) } _SEH2_END - SURFACE_UnlockSurface(psurf); + SURFACE_UnlockSurface(psurf); } return hbmp; @@ -834,25 +821,6 @@ NtGdiSetPixel( /* Internal Functions */ -UINT FASTCALL -BITMAP_GetRealBitsPixel(UINT nBitsPixel) -{ - if (nBitsPixel <= 1) - return 1; - 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; -} - HBITMAP FASTCALL BITMAP_CopyBitmap(HBITMAP hBitmap) {