diff --git a/reactos/dll/win32/gdi32/objects/bitmap.c b/reactos/dll/win32/gdi32/objects/bitmap.c index 8d93036c7d9..18db05f2a61 100644 --- a/reactos/dll/win32/gdi32/objects/bitmap.c +++ b/reactos/dll/win32/gdi32/objects/bitmap.c @@ -3,6 +3,36 @@ #define NDEBUG #include +/* + * 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); } /* diff --git a/reactos/subsystems/win32/win32k/objects/bitmaps.c b/reactos/subsystems/win32/win32k/objects/bitmaps.c index c3b7e8f148b..8f75277ebcc 100644 --- a/reactos/subsystems/win32/win32k/objects/bitmaps.c +++ b/reactos/subsystems/win32/win32k/objects/bitmaps.c @@ -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; }