Author: jgardou Date: Fri Dec 24 20:29:25 2010 New Revision: 50133
URL: http://svn.reactos.org/svn/reactos?rev=50133&view=rev Log: [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.
Modified: trunk/reactos/dll/win32/gdi32/objects/bitmap.c trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c
Modified: trunk/reactos/dll/win32/gdi32/objects/bitmap.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/objects/bit... ============================================================================== --- trunk/reactos/dll/win32/gdi32/objects/bitmap.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/gdi32/objects/bitmap.c [iso-8859-1] Fri Dec 24 20:29:25 2010 @@ -2,6 +2,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 @@ LPBITMAPINFO lpbmi, UINT uUsage) { - INT Ret = 0; - UINT cjBmpScanSize; - PVOID pvSafeBits = lpvBits; - - if (!hDC || !GdiIsHandleValid((HGDIOBJ)hDC)) - { - GdiSetLastError(ERROR_INVALID_PARAMETER); - return Ret; - } - - cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines); - - if ( lpvBits ) - { - if ( lpbmi ) - { + UINT cjBmpScanSize; + UINT cjInfoSize; + + if (!hDC || !GdiIsHandleValid((HGDIOBJ)hDC) || !lpbmi) + { + GdiSetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines); + cjInfoSize = DIB_BitmapInfoSize(lpbmi, uUsage); + + 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); }
/*
Modified: trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/obj... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/objects/bitmaps.c [iso-8859-1] Fri Dec 24 20:29:25 2010 @@ -170,11 +170,18 @@ 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; }