mirror of
https://github.com/reactos/reactos.git
synced 2025-01-02 20:43:18 +00:00
[GDI32]
- 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:
parent
23499a2d4d
commit
1513741845
2 changed files with 60 additions and 42 deletions
|
@ -3,6 +3,36 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#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.
|
* Return the full scan size for a bitmap.
|
||||||
*
|
*
|
||||||
|
@ -391,59 +421,40 @@ GetDIBits(
|
||||||
LPBITMAPINFO lpbmi,
|
LPBITMAPINFO lpbmi,
|
||||||
UINT uUsage)
|
UINT uUsage)
|
||||||
{
|
{
|
||||||
INT Ret = 0;
|
UINT cjBmpScanSize;
|
||||||
UINT cjBmpScanSize;
|
UINT cjInfoSize;
|
||||||
PVOID pvSafeBits = lpvBits;
|
|
||||||
|
|
||||||
if (!hDC || !GdiIsHandleValid((HGDIOBJ)hDC))
|
if (!hDC || !GdiIsHandleValid((HGDIOBJ)hDC) || !lpbmi)
|
||||||
{
|
{
|
||||||
GdiSetLastError(ERROR_INVALID_PARAMETER);
|
GdiSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return Ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines);
|
cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines);
|
||||||
|
cjInfoSize = DIB_BitmapInfoSize(lpbmi, uUsage);
|
||||||
|
|
||||||
if ( lpvBits )
|
if ( lpvBits )
|
||||||
{
|
{
|
||||||
if ( lpbmi )
|
|
||||||
{
|
|
||||||
if ( lpbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
|
if ( lpbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
|
||||||
{
|
{
|
||||||
if ( lpbmi->bmiHeader.biCompression == BI_JPEG ||
|
if ( lpbmi->bmiHeader.biCompression == BI_JPEG ||
|
||||||
lpbmi->bmiHeader.biCompression == BI_PNG )
|
lpbmi->bmiHeader.biCompression == BI_PNG )
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return Ret;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ULONG)lpvBits & (sizeof(DWORD) - 1))
|
return NtGdiGetDIBitsInternal(hDC,
|
||||||
{
|
|
||||||
pvSafeBits = RtlAllocateHeap(RtlGetProcessHeap(), 0, cjBmpScanSize);
|
|
||||||
if (!pvSafeBits)
|
|
||||||
return Ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ret = NtGdiGetDIBitsInternal(hDC,
|
|
||||||
hbmp,
|
hbmp,
|
||||||
uStartScan,
|
uStartScan,
|
||||||
cScanLines,
|
cScanLines,
|
||||||
pvSafeBits,
|
lpvBits,
|
||||||
lpbmi,
|
lpbmi,
|
||||||
uUsage,
|
uUsage,
|
||||||
cjBmpScanSize,
|
cjBmpScanSize,
|
||||||
0);
|
cjInfoSize);
|
||||||
if (lpvBits != pvSafeBits)
|
|
||||||
{
|
|
||||||
if (Ret)
|
|
||||||
{
|
|
||||||
RtlCopyMemory(lpvBits, pvSafeBits, cjBmpScanSize);
|
|
||||||
}
|
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
|
|
||||||
}
|
|
||||||
return Ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -170,11 +170,18 @@ NtGdiCreateBitmap(
|
||||||
iFormat = BitmapFormat(cBitsPixel, BI_RGB);
|
iFormat = BitmapFormat(cBitsPixel, BI_RGB);
|
||||||
|
|
||||||
/* Check parameters */
|
/* 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",
|
DPRINT1("Width = %d, Height = %d BitsPixel = %d\n",
|
||||||
nWidth, nHeight, cBitsPixel);
|
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;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue