- 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:
Timo Kreuzer 2011-01-09 18:38:41 +00:00
parent 3ecc17156e
commit 39b87b357f
4 changed files with 29 additions and 71 deletions

View file

@ -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:

View file

@ -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

View file

@ -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]

View file

@ -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)
{