mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 19:03: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:
|
case BI_RGB:
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
case BI_BITFIELDS:
|
case BI_BITFIELDS:
|
||||||
switch (Bits)
|
if (cBits <= 1) return BMF_1BPP;
|
||||||
{
|
if (cBits <= 4) return BMF_4BPP;
|
||||||
case 1:
|
if (cBits <= 8) return BMF_8BPP;
|
||||||
return BMF_1BPP;
|
if (cBits <= 16) return BMF_16BPP;
|
||||||
case 4:
|
if (cBits <= 24) return BMF_24BPP;
|
||||||
return BMF_4BPP;
|
if (cBits <= 32) return BMF_32BPP;
|
||||||
case 8:
|
|
||||||
return BMF_8BPP;
|
|
||||||
case 16:
|
|
||||||
return BMF_16BPP;
|
|
||||||
case 24:
|
|
||||||
return BMF_24BPP;
|
|
||||||
case 32:
|
|
||||||
return BMF_32BPP;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case BI_RLE4:
|
case BI_RLE4:
|
||||||
|
|
|
@ -11,7 +11,6 @@ typedef struct tagBITMAPV5INFO
|
||||||
INT APIENTRY BITMAP_GetObject(SURFACE * bmp, INT count, LPVOID buffer);
|
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 IntCreateBitmap(IN SIZEL Size, IN LONG Width, IN ULONG Format, IN ULONG Flags, IN PVOID Bits);
|
||||||
HBITMAP FASTCALL BITMAP_CopyBitmap (HBITMAP hBitmap);
|
HBITMAP FASTCALL BITMAP_CopyBitmap (HBITMAP hBitmap);
|
||||||
UINT FASTCALL BITMAP_GetRealBitsPixel(UINT nBitsPixel);
|
|
||||||
|
|
||||||
HBITMAP
|
HBITMAP
|
||||||
APIENTRY
|
APIENTRY
|
||||||
|
|
|
@ -125,7 +125,7 @@ SURFACE_bSetBitmapBits(
|
||||||
#define GDIDEV(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))
|
#define GDIDEV(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))
|
||||||
#define GDIDEVFUNCS(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))->DriverFunctions
|
#define GDIDEVFUNCS(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))->DriverFunctions
|
||||||
|
|
||||||
ULONG FASTCALL BitmapFormat (WORD Bits, DWORD Compression);
|
ULONG FASTCALL BitmapFormat(ULONG cBits, ULONG iCompression);
|
||||||
extern UCHAR gajBitsPerFormat[];
|
extern UCHAR gajBitsPerFormat[];
|
||||||
#define BitsPerFormat(Format) gajBitsPerFormat[Format]
|
#define BitsPerFormat(Format) gajBitsPerFormat[Format]
|
||||||
|
|
||||||
|
|
|
@ -161,60 +161,47 @@ NtGdiCreateBitmap(
|
||||||
IN OPTIONAL LPBYTE pUnsafeBits)
|
IN OPTIONAL LPBYTE pUnsafeBits)
|
||||||
{
|
{
|
||||||
HBITMAP hbmp;
|
HBITMAP hbmp;
|
||||||
ULONG cjWidthBytes, iFormat;
|
ULONG cRealBpp, cjWidthBytes, iFormat;
|
||||||
|
ULONGLONG cjSize;
|
||||||
|
|
||||||
/* NOTE: Windows also doesn't store nr. of planes separately! */
|
/* Calculate bitmap format and real bits per pixel. */
|
||||||
cBitsPixel = BITMAP_GetRealBitsPixel(cBitsPixel * cPlanes);
|
iFormat = BitmapFormat(cBitsPixel * cPlanes, BI_RGB);
|
||||||
|
cRealBpp = gajBitsPerFormat[iFormat];
|
||||||
|
|
||||||
/* Calculate bitmap format */
|
/* Calculate width and image size in bytes */
|
||||||
iFormat = BitmapFormat(cBitsPixel, BI_RGB);
|
cjWidthBytes = WIDTH_BYTES_ALIGN16(nWidth, cRealBpp);
|
||||||
|
cjSize = cjWidthBytes * nHeight;
|
||||||
|
|
||||||
/* Check parameters */
|
/* Check parameters (possible overflow of cjWidthBytes!) */
|
||||||
if (iFormat == 0 || nWidth <= 0 || nHeight <= 0)
|
if (iFormat == 0 || nWidth <= 0 || nWidth >= 0x8000000 || nHeight <= 0 ||
|
||||||
|
cBitsPixel > 32 || cPlanes > 32 || cjSize >= 0x100000000ULL)
|
||||||
{
|
{
|
||||||
DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
|
DPRINT1("Invalid bitmap format! Width=%d, Height=%d, Bpp=%d, Planes=%d\n",
|
||||||
nWidth, nHeight, cBitsPixel);
|
nWidth, nHeight, cBitsPixel, cPlanes);
|
||||||
EngSetLastError(ERROR_INVALID_PARAMETER);
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel)*nHeight >= 0x8000000)
|
/* Call internal function. */
|
||||||
{
|
hbmp = GreCreateBitmapEx(nWidth, nHeight, 0, iFormat, 0, 0, NULL, DDB_SURFACE);
|
||||||
/* I just can't get enough, I just can't get enough */
|
|
||||||
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Make sure that cjBits will not overflow */
|
if (pUnsafeBits && hbmp)
|
||||||
cjWidthBytes = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
|
|
||||||
if ((ULONGLONG)cjWidthBytes * nHeight >= 0x100000000ULL)
|
|
||||||
{
|
{
|
||||||
DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
|
PSURFACE psurf = SURFACE_LockSurface(hbmp);
|
||||||
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);
|
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
ProbeForRead(pUnsafeBits, cjWidthBytes * nHeight, 1);
|
ProbeForRead(pUnsafeBits, cjSize, 1);
|
||||||
UnsafeSetBitmapBits(psurf, 0, pUnsafeBits);
|
UnsafeSetBitmapBits(psurf, 0, pUnsafeBits);
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
SURFACE_UnlockSurface(psurf);
|
SURFACE_UnlockSurface(psurf);
|
||||||
SURFACE_FreeSurfaceByHandle(hbmp);
|
SURFACE_FreeSurfaceByHandle(hbmp);
|
||||||
_SEH2_YIELD(return NULL;)
|
_SEH2_YIELD(return NULL;)
|
||||||
}
|
}
|
||||||
_SEH2_END
|
_SEH2_END
|
||||||
|
|
||||||
SURFACE_UnlockSurface(psurf);
|
SURFACE_UnlockSurface(psurf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hbmp;
|
return hbmp;
|
||||||
|
@ -834,25 +821,6 @@ NtGdiSetPixel(
|
||||||
|
|
||||||
/* Internal Functions */
|
/* 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
|
HBITMAP FASTCALL
|
||||||
BITMAP_CopyBitmap(HBITMAP hBitmap)
|
BITMAP_CopyBitmap(HBITMAP hBitmap)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue