- remove useless memory reallocation : the buffer size must be dword aligned, we have no way to guarantee the buffer location will be.
  - pass BITMAPINFO pointer size to NtGdiGetDIBitsInternal
[WIN32K]
  - Improve "not enough memory" check when creating a bitmap
  - use correct function to set the last error.

svn path=/trunk/; revision=50133
This commit is contained in:
Jérôme Gardou 2010-12-24 20:29:25 +00:00
parent 23499a2d4d
commit 1513741845
2 changed files with 60 additions and 42 deletions

View file

@ -3,6 +3,36 @@
#define NDEBUG
#include <debug.h>
/*
* DIB_BitmapInfoSize
*
* Return the size of the bitmap info structure including color table.
* 11/16/1999 (RJJ) lifted from wine
*/
INT FASTCALL DIB_BitmapInfoSize(const BITMAPINFO * info, WORD coloruse)
{
unsigned int colors, size, masks = 0;
if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
return sizeof(BITMAPCOREHEADER) + colors *
((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
}
else /* assume BITMAPINFOHEADER */
{
colors = info->bmiHeader.biClrUsed;
if (colors > 256) colors = 256;
if (!colors && (info->bmiHeader.biBitCount <= 8))
colors = 1 << info->bmiHeader.biBitCount;
if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
}
}
/*
* Return the full scan size for a bitmap.
*
@ -391,59 +421,40 @@ GetDIBits(
LPBITMAPINFO lpbmi,
UINT uUsage)
{
INT Ret = 0;
UINT cjBmpScanSize;
PVOID pvSafeBits = lpvBits;
UINT cjBmpScanSize;
UINT cjInfoSize;
if (!hDC || !GdiIsHandleValid((HGDIOBJ)hDC))
{
GdiSetLastError(ERROR_INVALID_PARAMETER);
return Ret;
}
if (!hDC || !GdiIsHandleValid((HGDIOBJ)hDC) || !lpbmi)
{
GdiSetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines);
cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines);
cjInfoSize = DIB_BitmapInfoSize(lpbmi, uUsage);
if ( lpvBits )
{
if ( lpbmi )
{
if ( lpvBits )
{
if ( lpbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
{
if ( lpbmi->bmiHeader.biCompression == BI_JPEG ||
lpbmi->bmiHeader.biCompression == BI_PNG )
{
SetLastError(ERROR_INVALID_PARAMETER);
return Ret;
}
if ( lpbmi->bmiHeader.biCompression == BI_JPEG ||
lpbmi->bmiHeader.biCompression == BI_PNG )
{
SetLastError(ERROR_INVALID_PARAMETER);
return 0;
}
}
}
}
if ((ULONG)lpvBits & (sizeof(DWORD) - 1))
{
pvSafeBits = RtlAllocateHeap(RtlGetProcessHeap(), 0, cjBmpScanSize);
if (!pvSafeBits)
return Ret;
}
}
Ret = NtGdiGetDIBitsInternal(hDC,
return NtGdiGetDIBitsInternal(hDC,
hbmp,
uStartScan,
cScanLines,
pvSafeBits,
lpvBits,
lpbmi,
uUsage,
cjBmpScanSize,
0);
if (lpvBits != pvSafeBits)
{
if (Ret)
{
RtlCopyMemory(lpvBits, pvSafeBits, cjBmpScanSize);
}
RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
}
return Ret;
cjInfoSize);
}
/*

View file

@ -170,11 +170,18 @@ NtGdiCreateBitmap(
iFormat = BitmapFormat(cBitsPixel, BI_RGB);
/* Check parameters */
if (iFormat == 0 || nWidth <= 0 || nWidth >= 0x8000000 || nHeight <= 0)
if (iFormat == 0 || nWidth <= 0 || nHeight <= 0)
{
DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
nWidth, nHeight, cBitsPixel);
EngSetLastError(ERROR_INVALID_PARAMETER);
SetLastWin32Error(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 */
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}