mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 17:56:00 +00:00
[WIN32K]
- In BitmapFormat, allow intermediate bpp values, use ULONG as parameter type, instead of WORD and DWORD - In NtGdiCreateBitmap get the real bpp value from the gajBitsPerFormat array - Add back check of too large nWidth (needed to make sure, cjWidthBytes didn't overflow) - Merge all parameter checks - Check cPlanes and cBitsPixel paramters explicitly - Use GreCreateBitmapEx - Remove BITMAP_GetRealBitsPixel svn path=/trunk/; revision=50343
This commit is contained in:
parent
3ecc17156e
commit
39b87b357f
4 changed files with 29 additions and 71 deletions
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue