Author: tkreuzer Date: Tue Aug 14 22:27:00 2012 New Revision: 57078
URL: http://svn.reactos.org/svn/reactos?rev=57078&view=rev Log: [WIN32K/GDI32] - Many changes and bugfixes to the new DIB code It's in a usable state now, also working with the new diblib. Still lots of bugs and failures need to be fixed.
Added: branches/dib_rewrite/win32ss/gdi/gdi32/objects/dibitmap.c (with props) Modified: branches/dib_rewrite/win32ss/CMakeLists.txt branches/dib_rewrite/win32ss/gdi/eng/bitblt_new.c branches/dib_rewrite/win32ss/gdi/gdi32/objects/bitmap.c branches/dib_rewrite/win32ss/gdi/ntgdi/brush.c branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.c branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.h branches/dib_rewrite/win32ss/gdi/ntgdi/dibobj.c branches/dib_rewrite/win32ss/user/ntuser/clipboard.c
Modified: branches/dib_rewrite/win32ss/CMakeLists.txt URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/CMakeLists.t... ============================================================================== --- branches/dib_rewrite/win32ss/CMakeLists.txt [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/CMakeLists.txt [iso-8859-1] Tue Aug 14 22:27:00 2012 @@ -1,5 +1,5 @@
-set(USE_DIBLIB FALSE) +set(USE_DIBLIB TRUE)
# Give WIN32 subsystem its own project. PROJECT(WIN32SS) @@ -150,6 +150,7 @@ gdi/ntgdi/dcstate.c gdi/ntgdi/dcutil.c gdi/ntgdi/device.c + gdi/ntgdi/dibobj.c gdi/ntgdi/dibitmap.c gdi/ntgdi/drawing.c gdi/ntgdi/fillshap.c
Modified: branches/dib_rewrite/win32ss/gdi/eng/bitblt_new.c URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/eng/bitb... ============================================================================== --- branches/dib_rewrite/win32ss/gdi/eng/bitblt_new.c [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/gdi/eng/bitblt_new.c [iso-8859-1] Tue Aug 14 22:27:00 2012 @@ -5,12 +5,14 @@
#define SURFOBJ_flags(pso) (CONTAINING_RECORD(pso, SURFACE, SurfObj)->flags)
+#if 0 // FIXME this needs to be updated, once we use the new structure XCLIPOBJ gxcoTrivial = { {0, {LONG_MIN, LONG_MIN, LONG_MAX, LONG_MAX}, DC_TRIVIAL, FC_RECT, TC_RECTANGLES, 0}, 0, 0, 0 }; +#endif
static
Modified: branches/dib_rewrite/win32ss/gdi/gdi32/objects/bitmap.c URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/gdi32/ob... ============================================================================== --- branches/dib_rewrite/win32ss/gdi/gdi32/objects/bitmap.c [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/gdi/gdi32/objects/bitmap.c [iso-8859-1] Tue Aug 14 22:27:00 2012 @@ -382,125 +382,6 @@ }
-INT -WINAPI -GetDIBits( - HDC hDC, - HBITMAP hbmp, - UINT uStartScan, - UINT cScanLines, - LPVOID lpvBits, - LPBITMAPINFO lpbmi, - UINT uUsage) -{ - 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 0; - } - } - } - - return NtGdiGetDIBitsInternal(hDC, - hbmp, - uStartScan, - cScanLines, - lpvBits, - lpbmi, - uUsage, - cjBmpScanSize, - cjInfoSize); -} - -/* - * @implemented - */ -HBITMAP -WINAPI -CreateDIBitmap( HDC hDC, - const BITMAPINFOHEADER *Header, - DWORD Init, - LPCVOID Bits, - const BITMAPINFO *Data, - UINT ColorUse) -{ - LONG width, height, compr, dibsize; - WORD planes, bpp; -// PDC_ATTR pDc_Attr; - UINT InfoSize = 0; - UINT cjBmpScanSize = 0; - HBITMAP hBmp; - NTSTATUS Status = STATUS_SUCCESS; - - if (!Header) return 0; - - if (DIB_GetBitmapInfo(Header, &width, &height, &planes, &bpp, &compr, &dibsize) == -1) - { - GdiSetLastError(ERROR_INVALID_PARAMETER); - return NULL; - } - -// For Icm support. -// GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr)) - - if(Data) - { - _SEH2_TRY - { - cjBmpScanSize = GdiGetBitmapBitsSize((BITMAPINFO *)Data); - CalculateColorTableSize(&Data->bmiHeader, &ColorUse, &InfoSize); - InfoSize += Data->bmiHeader.biSize; - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Status = _SEH2_GetExceptionCode(); - } - _SEH2_END - } - - if(!NT_SUCCESS(Status)) - { - GdiSetLastError(ERROR_INVALID_PARAMETER); - return NULL; - } - - DPRINT("pBMI %x, Size bpp %d, dibsize %d, Conv %d, BSS %d\n", Data,bpp,dibsize,InfoSize,cjBmpScanSize); - - if ( !width || !height ) - hBmp = GetStockObject(DEFAULT_BITMAP); - else - { - hBmp = NtGdiCreateDIBitmapInternal(hDC, - width, - height, - Init, - (LPBYTE)Bits, - (LPBITMAPINFO)Data, - ColorUse, - InfoSize, - cjBmpScanSize, - 0, - 0); - } - return hBmp; -}
/* * @implemented @@ -608,9 +489,9 @@ DWORD Height, int XSrc, int YSrc, - UINT StartScan, - UINT ScanLines, - CONST VOID *Bits, + UINT uStartScan, + UINT cScanLines, + CONST VOID *pvBits, CONST BITMAPINFO *lpbmi, UINT ColorUse) { @@ -620,9 +501,9 @@ INT LinesCopied = 0; UINT cjBmpScanSize = 0; BOOL Hit = FALSE; - PVOID pvSafeBits = (PVOID)Bits; - - if ( !ScanLines || !lpbmi || !Bits ) + PVOID pvAlignedBits = (PVOID)pvBits; + + if ( !cScanLines || !lpbmi || !pvBits ) return 0;
if ( ColorUse && ColorUse != DIB_PAL_COLORS && ColorUse != DIB_PAL_COLORS+1 ) @@ -645,9 +526,9 @@ Height, XSrc, YSrc, - StartScan, - ScanLines, - Bits, + uStartScan, + cScanLines, + pvBits, lpbmi, ColorUse); else @@ -667,9 +548,9 @@ Height, XSrc, YSrc, - StartScan, - ScanLines, - Bits, + uStartScan, + cScanLines, + pvBits, lpbmi, ColorUse); } @@ -677,35 +558,38 @@ } } #endif - cjBmpScanSize = DIB_BitmapMaxBitsSize((LPBITMAPINFO)lpbmi, ScanLines); - - pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize); - if (pvSafeBits) - { - _SEH2_TRY - { - RtlCopyMemory( pvSafeBits, Bits, cjBmpScanSize); - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - Hit = TRUE; - } - _SEH2_END - - if (Hit) - { - // We don't die, we continue on with a allocated safe pointer to kernel - // space..... - DPRINT1("SetDIBitsToDevice fail to read BitMapInfo: %x or Bits: %x & Size: %d\n",pConvertedInfo,Bits,cjBmpScanSize); - } - DPRINT("SetDIBitsToDevice Allocate Bits %d!!!\n", cjBmpScanSize); - } + cjBmpScanSize = DIB_BitmapMaxBitsSize((LPBITMAPINFO)lpbmi, cScanLines); + + /* Check if the bits buffer is not DWORD aligned */ + if ((ULONG_PTR)pvBits & (sizeof(DWORD) - 1)) + { + /* The given buffer is unaligned, allocate an aligned buffer */ + pvAlignedBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize); + if (!pvAlignedBits) + { + DPRINT1("Failed to allocate aligned buffer.\n"); + goto cleanup; + } + + /* Use SEH to copy the bitmap data */ + _SEH2_TRY + { + RtlCopyMemory(pvAlignedBits, pvBits, cjBmpScanSize); + } + _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) + { + DPRINT1("Failed to copy the bitmap to the aligned buffer.\n"); + _SEH2_YIELD(goto cleanup;) + } + _SEH2_END + }
if (!GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr)) { SetLastError(ERROR_INVALID_PARAMETER); - return 0; - } + goto cleanup; + } + /* if ( !pDc_Attr || // DC is Public ColorUse == DIB_PAL_COLORS || @@ -713,16 +597,16 @@ (pConvertedInfo->bmiHeader.biCompression == BI_JPEG || pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/ { - LinesCopied = NtGdiSetDIBitsToDeviceInternal( hdc, + LinesCopied = NtGdiSetDIBitsToDeviceInternal(hdc, XDest, YDest, Width, Height, XSrc, YSrc, - StartScan, - ScanLines, - (LPBYTE)pvSafeBits, + uStartScan, + cScanLines, + pvAlignedBits, (LPBITMAPINFO)pConvertedInfo, ColorUse, cjBmpScanSize, @@ -730,9 +614,12 @@ TRUE, NULL); } - if ( Bits != pvSafeBits) - RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits); - if (lpbmi != pConvertedInfo) + +cleanup: + /* Cleanup */ + if (pvAlignedBits != pvBits) + RtlFreeHeap(RtlGetProcessHeap(), 0, pvAlignedBits); + if (pConvertedInfo != lpbmi) RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
return LinesCopied; @@ -885,3 +772,4 @@ return LinesCopied; }
+#include "dibitmap.c"
Added: branches/dib_rewrite/win32ss/gdi/gdi32/objects/dibitmap.c URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/gdi32/ob... ============================================================================== --- branches/dib_rewrite/win32ss/gdi/gdi32/objects/dibitmap.c (added) +++ branches/dib_rewrite/win32ss/gdi/gdi32/objects/dibitmap.c [iso-8859-1] Tue Aug 14 22:27:00 2012 @@ -1,0 +1,349 @@ + + +#define WIDTH_BYTES_ALIGN32(cx, bpp) ((((cx) * (bpp) + 31) & ~31) >> 3) + +ULONG +NTAPI +DibGetBitmapInfoSize( + _In_ const BITMAPINFO *pbmi, + _In_ ULONG iUsage) +{ + ULONG cjHeaderSize, cBitsPixel, cColors, cMaxColors; + + cjHeaderSize = pbmi->bmiHeader.biSize; + + if ((cjHeaderSize < sizeof(BITMAPCOREHEADER)) || + ((LONG)cjHeaderSize < 0)) + { + return 0; + } + + /* Check for BITMAPCOREINFO */ + if (cjHeaderSize < sizeof(BITMAPINFOHEADER)) + { + PBITMAPCOREHEADER pbch = (PBITMAPCOREHEADER)pbmi; + + cBitsPixel = pbch->bcBitCount; + cColors = (cBitsPixel <= 8) ? (1 << cBitsPixel) : 0; + return sizeof(BITMAPCOREHEADER) + cColors * + ((iUsage == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD)); + } + else /* Use BITMAPINFOHEADER */ + { + /* Check if the DIB uses bitfields */ + if (pbmi->bmiHeader.biCompression == BI_BITFIELDS) + { + /* Check for V4/v5 info */ + if (cjHeaderSize >= sizeof(BITMAPV4HEADER)) + { + /* There are no colors or masks */ + return cjHeaderSize; + } + else + { + /* The color table is 3 masks */ + return cjHeaderSize + 3 * sizeof(RGBQUAD); + } + } + + cBitsPixel = pbmi->bmiHeader.biBitCount; + if (cBitsPixel > 8) + return cjHeaderSize; + + cMaxColors = (1 << cBitsPixel); + cColors = pbmi->bmiHeader.biClrUsed; + if ((cColors == 0) || (cColors > cMaxColors)) cColors = cMaxColors; + + if (iUsage == DIB_RGB_COLORS) + return cjHeaderSize + cColors * sizeof(RGBQUAD); + else + return cjHeaderSize + cColors * sizeof(WORD); + } +} + + +static +PBITMAPINFO +ConvertBitmapCoreInfo( + _In_ const BITMAPINFO *pbmiCore, + _In_ UINT iUsage) +{ + const BITMAPCOREINFO *pbci = (const BITMAPCOREINFO *)pbmiCore; + BITMAPINFO *pbmi; + ULONG i, cColors, cjColorTable; + + /* Get the number of colors in bmciColors */ + if (pbci->bmciHeader.bcBitCount == 1) cColors = 2; + else if (pbci->bmciHeader.bcBitCount == 4) cColors = 16; + else if (pbci->bmciHeader.bcBitCount == 8) cColors = 256; + else cColors = 0; + + /* Calculate the size of the output color table */ + if (iUsage == DIB_RGB_COLORS) + cjColorTable = + cColors * sizeof(RGBTRIPLE); + else + cjColorTable = cColors * sizeof(WORD); + + /* Allocate the BITMAPINFO */ + pbmi = HeapAlloc(GetProcessHeap(), 0, sizeof(BITMAPINFOHEADER) + cjColorTable); + if (!pbmi) return NULL; + + /* Fill the BITMAPINFOHEADER */ + pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biWidth = pbci->bmciHeader.bcWidth; + pbmi->bmiHeader.biHeight = pbci->bmciHeader.bcHeight; + pbmi->bmiHeader.biPlanes = pbci->bmciHeader.bcPlanes; + pbmi->bmiHeader.biBitCount = pbci->bmciHeader.bcBitCount; + pbmi->bmiHeader.biCompression = BI_RGB; + pbmi->bmiHeader.biSizeImage = 0; + pbmi->bmiHeader.biXPelsPerMeter = 0; + pbmi->bmiHeader.biYPelsPerMeter = 0; + pbmi->bmiHeader.biClrUsed = cColors; + pbmi->bmiHeader.biClrImportant = cColors; + + /* Check what type of color table we have */ + if (iUsage == DIB_RGB_COLORS) + { + /* The colors are an array of RGBTRIPLE / RGBQUAD */ + RGBTRIPLE *prgbIn = (RGBTRIPLE*)pbci->bmciColors; + RGBQUAD *prgbOut = (RGBQUAD*)pbmi->bmiColors; + + for (i = 0; i < cColors; i++) + { + prgbOut[i].rgbRed = prgbIn[i].rgbtRed; + prgbOut[i].rgbGreen = prgbIn[i].rgbtGreen; + prgbOut[i].rgbBlue = prgbIn[i].rgbtBlue; + prgbOut[i].rgbReserved = 0; + } + } + else + { + /* The colors are an array of WORD indices */ + PWORD pwColorsIn = (PWORD)pbci->bmciColors; + PWORD pwColorsOut = (PWORD)pbmi->bmiColors; + + for (i = 0; i < cColors; i++) + pwColorsOut[i] = pwColorsIn[i]; + + } + + return pbmi; +} + +VOID +WINAPI +ConvertBackToCoreInfo( + _In_ BITMAPCOREINFO *pbci, + _In_ const BITMAPINFO *pbmi, + _In_ UINT iUsage) +{ + ULONG i, cColors; + + pbci->bmciHeader.bcWidth = (WORD)pbmi->bmiHeader.biWidth; + pbci->bmciHeader.bcHeight = (WORD)pbmi->bmiHeader.biHeight; + pbci->bmciHeader.bcPlanes = (WORD)pbmi->bmiHeader.biPlanes; + pbci->bmciHeader.bcBitCount = (WORD)pbmi->bmiHeader.biBitCount; + if (pbci->bmciHeader.bcBitCount > 16) pbci->bmciHeader.bcBitCount = 24; + + /* Get the number of colors in bmciColors */ + if (pbci->bmciHeader.bcBitCount == 1) cColors = 2; + else if (pbci->bmciHeader.bcBitCount == 4) cColors = 16; + else if (pbci->bmciHeader.bcBitCount == 8) cColors = 256; + else cColors = 0; + + /* Check what type of color table we have */ + if (iUsage == DIB_RGB_COLORS) + { + /* The colors are an array of RGBTRIPLE / RGBQUAD */ + RGBTRIPLE *prgbOut = (RGBTRIPLE*)pbci->bmciColors; + RGBQUAD *prgbIn = (RGBQUAD*)pbmi->bmiColors; + + for (i = 0; i < cColors; i++) + { + prgbOut[i].rgbtRed = prgbIn[i].rgbRed; + prgbOut[i].rgbtGreen = prgbIn[i].rgbGreen; + prgbOut[i].rgbtBlue = prgbIn[i].rgbBlue; + } + } + else + { + /* The colors are an array of WORD indices */ + PWORD pwColorsOut = (PWORD)pbci->bmciColors; + PWORD pwColorsIn = (PWORD)pbmi->bmiColors; + + for (i = 0; i < cColors; i++) + pwColorsOut[i] = pwColorsIn[i]; + + } + +} + +HBITMAP +WINAPI +CreateDIBitmap( + _In_ HDC hdc, + _In_ const BITMAPINFOHEADER *pbmih, + _In_ DWORD fdwInit, + _In_ const VOID *pbInit, + _In_ const BITMAPINFO *pbmi, + _In_ UINT iUsage) +{ + LONG cx, cy; + BOOL bConvertedInfo = FALSE; + HBITMAP hbmp = NULL; + ULONG cjInfo, cjImageSize; + + if (pbmi) + { + if (pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER)) + { + pbmi = ConvertBitmapCoreInfo(pbmi, iUsage); + bConvertedInfo = TRUE; + } + + /* Get the size of the BITMAPINFO */ + cjInfo = DibGetBitmapInfoSize(pbmi, iUsage); + + /* Check if we have bits */ + if (pbInit) + { + /* Get the size of the image */ + cjImageSize = pbmi->bmiHeader.biSizeImage; + + /* Check if we need to calculate the size */ + if ((cjImageSize == 0) && + ((pbmi->bmiHeader.biCompression == BI_RGB) || + (pbmi->bmiHeader.biCompression == BI_BITFIELDS))) + { + /* Calculate the image size */ + cjImageSize = abs(pbmi->bmiHeader.biHeight) * + WIDTH_BYTES_ALIGN32(pbmi->bmiHeader.biWidth, + pbmi->bmiHeader.biBitCount); + } + } + } + else + { + cjInfo = 0; + } + + if (fdwInit & CBM_CREATDIB) + { + if (!pbmi) return NULL; + + //__debugbreak(); + return 0; + } + else + { + if (!pbmih) + { + SetLastError(ERROR_INVALID_PARAMETER); + goto cleanup; + } + + if (pbmih->biSize == sizeof(BITMAPCOREHEADER)) + { + PBITMAPCOREHEADER pbch = (PBITMAPCOREHEADER)pbmih; + cx = pbch->bcWidth; + cy = abs(pbch->bcHeight); + } + else if (pbmih->biSize >= sizeof(BITMAPINFOHEADER)) + { + cx = pbmih->biWidth; + cy = abs(pbmih->biHeight); + } + else + { + SetLastError(ERROR_INVALID_PARAMETER); + goto cleanup; + } + + if ((cx == 0) || (cy == 0)) + { + return GetStockObject(DEFAULT_BITMAP); + } + } + + + hbmp = NtGdiCreateDIBitmapInternal(hdc, + cx, + cy, + fdwInit, + (PVOID)pbInit, + (PVOID)pbmi, + iUsage, + cjInfo, + cjImageSize, + 0, + 0); + +cleanup: + if (bConvertedInfo && pbmi) HeapFree(GetProcessHeap(), 0, (PVOID)pbmi); + + return hbmp; +} + +INT +WINAPI +GetDIBits( + HDC hdc, + HBITMAP hbmp, + UINT uStartScan, + UINT cScanLines, + LPVOID pvBits, + LPBITMAPINFO pbmi, + UINT iUsage) +{ + UINT cjBmpScanSize; + UINT cjInfoSize; + INT iResult; + BITMAPCOREINFO *pbci = NULL; + + if (!hdc || !GdiIsHandleValid((HGDIOBJ)hdc) || !pbmi) + { + GdiSetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + if (pbmi && (pbmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))) + { + pbci = (BITMAPCOREINFO *)pbmi; + pbmi = ConvertBitmapCoreInfo(pbmi, iUsage); + if (!pbmi) + return 0; + } + + cjBmpScanSize = DIB_BitmapMaxBitsSize(pbmi, cScanLines); + cjInfoSize = DIB_BitmapInfoSize(pbmi, iUsage); + + if (pvBits ) + { + /* Check for compressed formats */ + if ((pbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) && + (pbmi->bmiHeader.biCompression >= BI_JPEG)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + } + + iResult = NtGdiGetDIBitsInternal(hdc, + hbmp, + uStartScan, + cScanLines, + pvBits, + pbmi, + iUsage, + cjBmpScanSize, + cjInfoSize); + + if (pbci) + { + ConvertBackToCoreInfo(pbci, pbmi, iUsage); + HeapFree(GetProcessHeap(), 0, (PVOID)pbmi); + } + + return iResult; +} +
Propchange: branches/dib_rewrite/win32ss/gdi/gdi32/objects/dibitmap.c ------------------------------------------------------------------------------ svn:eol-style = native
Modified: branches/dib_rewrite/win32ss/gdi/ntgdi/brush.c URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/ntgdi/br... ============================================================================== --- branches/dib_rewrite/win32ss/gdi/ntgdi/brush.c [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/gdi/ntgdi/brush.c [iso-8859-1] Tue Aug 14 22:27:00 2012 @@ -446,7 +446,7 @@ _SEH2_END;
/* Calculate the size of the bitmap info */ - cjInfoSize = GreGetBitmapInfoSize(pvSaveDIB, iUsage); + cjInfoSize = DibGetBitmapInfoSize(pvSaveDIB, iUsage);
/* Check sanity of the sizes */ if ((cjInfoSize < sizeof(BITMAPCOREHEADER)) || // info?
Modified: branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.c URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/ntgdi/di... ============================================================================== --- branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.c [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.c [iso-8859-1] Tue Aug 14 22:27:00 2012 @@ -26,6 +26,7 @@ pbmf->sizel.cy = pbch->bcHeight; pbmf->cBitsPixel = pbch->bcBitCount * pbch->bcPlanes; pbmf->iCompression = BI_RGB; + pbmf->cjImageSize = 0; } else { @@ -33,6 +34,7 @@ pbmf->sizel.cy = pbmi->bmiHeader.biHeight; pbmf->cBitsPixel = pbmi->bmiHeader.biBitCount * pbmi->bmiHeader.biPlanes; pbmf->iCompression = pbmi->bmiHeader.biCompression; + pbmf->cjImageSize = pbmi->bmiHeader.biSizeImage; }
/* Get the bitmap format */ @@ -43,6 +45,18 @@ { DPRINT1("Invalid format\n"); return FALSE; + } + + /* Check if this is an uncompressed format */ + if (pbmf->iFormat <= BMF_32BPP) + { + /* Calculate the image size */ + pbmf->cjWidthBytes = WIDTH_BYTES_ALIGN32(pbmf->sizel.cx, pbmf->cBitsPixel); + pbmf->cjImageSize = abs(pbmf->sizel.cy) * pbmf->cjWidthBytes; + } + else + { + pbmf->cjWidthBytes = 0; }
/* Check compressed format and top-down */ @@ -155,7 +169,7 @@ /* Normalize the size to the maximum possible */ cjInfo = min(cjInfo, sizeof(BITMAPV5HEADER) + 256 * sizeof(RGBQUAD));
- /* Check if the size is at least big enough for a core info */ + /* Check if the size is at least big enough for a core header */ if (cjInfo < sizeof(BITMAPCOREHEADER)) { return NULL; @@ -181,8 +195,9 @@ } _SEH2_END;
- /* Check if we have at least as much as the actual header size */ - if (cjInfo >= pbmi->bmiHeader.biSize) + /* Check if the header size is in the valid range */ + if ((pbmi->bmiHeader.biSize >= sizeof(BITMAPCOREHEADER)) && + (pbmi->bmiHeader.biSize <= cjInfo)) { /* Calculate the real size of the bitmap info */ cjInfo = DibGetBitmapInfoSize(pbmi, iUsage); @@ -414,6 +429,17 @@ return NULL; }
+ /* Check if we have bitmap bits */ + if (pvBits) + { + /* Check if the image size is too large */ + if (bitmapformat.cjImageSize > cjMaxBits) + { + __debugbreak(); + return NULL; + } + } + /* Handle top-down bitmaps */ if (bitmapformat.sizel.cy < 0) fjBitmap |= BMF_TOPDOWN;
@@ -439,9 +465,8 @@ return NULL; }
- /* Dereference the old palette and set the new */ - PALETTE_ShareUnlockPalette(psurf->ppal); - psurf->ppal = ppal; + /* Set new palette for the surface */ + SURFACE_vSetPalette(psurf, ppal);
/* Return the surface */ return psurf; @@ -454,7 +479,7 @@ APIENTRY NtGdiCreateDIBSection( _In_ HDC hdc, - _In_ OPTIONAL HANDLE hSectionApp, + _In_opt_ HANDLE hSectionApp, _In_ DWORD dwOffset, _In_ LPBITMAPINFO pbmiUser, _In_ DWORD iUsage, @@ -571,10 +596,10 @@ _In_ HANDLE hcmXform) { PDC pdc; - PSURFACE psurfDIB, psurfDC, psurfBmp; + PSURFACE psurfDIB = NULL, psurfDC, psurfBmp; ULONG iFormat; - PPALETTE ppalBmp; - HBITMAP hbmp; + PPALETTE ppalBmp = NULL; + HBITMAP hbmp = NULL;
/* Check if we got a DC */ if (hdc) @@ -592,22 +617,28 @@ { /* No DC */ pdc = NULL; + psurfDC = NULL; }
if (pjInit) { + if (!pbmi) goto cleanup; + + /* Create a surface from the DIB */ psurfDIB = DibCreateDIBSurface(pbmi, pdc, iUsage, 0, pjInit, cjMaxBits); - } - + + if (!psurfDIB) goto cleanup; + }
if (fInit & CBM_CREATDIB) { if (iUsage == 2) goto cleanup; + if (!psurfDIB) goto cleanup;
/* Need a DC for DIB_PAL_COLORS */ if ((iUsage == DIB_PAL_COLORS) && !pdc) goto cleanup; @@ -634,7 +665,9 @@ } else { - __debugbreak(); + // FIXME: use default PDEV surface? + iFormat = BMF_32BPP; + ppalBmp = &gpalRGB; }
GDIOBJ_vReferenceObjectByPointer(&ppalBmp->BaseObject); @@ -646,6 +679,7 @@ { /* Set new palette for the bitmap */ SURFACE_vSetPalette(psurfBmp, ppalBmp); + ppalBmp = NULL;
if (pjInit) { @@ -678,10 +712,11 @@
cleanup: - + if (psurfDIB) GDIOBJ_vDeleteObject(&psurfDIB->BaseObject); if (ppalBmp) PALETTE_ShareUnlockPalette(ppalBmp); - - return 0; + if (pdc) DC_UnlockDc(pdc); + + return hbmp; }
HBITMAP @@ -705,6 +740,12 @@
//__debugbreak();
+ if (iUsage >= 2) + { + EngSetLastError(ERROR_INVALID_PARAMETER); + return NULL; + } + if (fInit & CBM_INIT) { if (pjInit) @@ -712,6 +753,10 @@ hSecure = EngSecureMem(pjInit, cjMaxBits); if (!hSecure) return NULL; + } + else + { + fInit &= ~CBM_INIT; } } else @@ -1216,6 +1261,7 @@ NULL, pdc->rosdc.CombinedClip, &exlo.xlo, + &pdc->dclevel.ca, &rcDst, &rcSrc, NULL, @@ -1232,6 +1278,14 @@ return bResult ? cySrc : 0; }
+/*! + * \brief + * \param [in] iStartScan - Specifies the number of the starting scanline for + * the part of the dib that is contained in the buffer that pjBits points + * to. A value of 0 refers to the pixel row in the dib with the highest + * y coordinate. + * + */ INT APIENTRY NtGdiSetDIBitsToDeviceInternal( @@ -1244,7 +1298,7 @@ _In_ INT ySrc, _In_ DWORD iStartScan, _In_ DWORD cNumScan, - _In_ LPBYTE pjInitBits, + _In_ LPBYTE pjBits, _In_ LPBITMAPINFO pbmiUser, _In_ DWORD iUsage, _In_ UINT cjMaxBits, @@ -1254,7 +1308,20 @@ { PBITMAPINFO pbmi; HANDLE hSecure; - INT iResult = 0; + ULONG cyDIB; + INT yTop, iResult; +__debugbreak(); + /* Check if parameters are valid */ + if ((cNumScan == 0) || (cx >= INT_MAX) || (cy >= INT_MAX)) + { + return 0; + } + + /* Check if the bitmap buffer is not NULL and DWORD aligned */ + if (!pjBits || ((ULONG_PTR)pjBits & (sizeof(DWORD) - 1))) + { + return 0; + }
/* Capture a safe copy of the bitmap info */ pbmi = DibProbeAndCaptureBitmapInfo(pbmiUser, iUsage, &cjMaxInfo); @@ -1265,32 +1332,79 @@ }
/* Secure the user mode buffer for the bits */ - hSecure = EngSecureMemForRead(pjInitBits, cjMaxBits); - if (hSecure) - { - /* Call the internal function with the secure pointers */ - iResult = GreStretchDIBitsInternal(hdcDest, - xDst, - yDst, - cx, - cy, - xSrc, - ySrc, - cx, - cy, - pjInitBits, - pbmi, - iUsage, - MAKEROP4(SRCCOPY, SRCCOPY), - cjMaxInfo, - cjMaxBits, - bTransformCoordinates, - hcmXform); - - /* Unsecure the memory */ - EngUnsecureMem(hSecure); - } - + hSecure = EngSecureMemForRead(pjBits, cjMaxBits); + if (!hSecure) + { + iResult = 0; + goto leave; + } + + /* Even when nothing is copied, the function returns the scanlines */ + iResult = cNumScan; + + /* Get the absolute height of the DIB */ + cyDIB = abs(pbmi->bmiHeader.biHeight); + + /* Bail out if the scanlines are outside of the DIB */ + if (iStartScan >= cyDIB) goto leave; + + /* Limit the number of scanlines to the DIB size */ + cNumScan = min(cNumScan, cyDIB - iStartScan); + + /* Calculate the y-origin of the given DIB data */ + yTop = cyDIB - (iStartScan + cNumScan); + + /* Bail out if the intersecion between scanlines and copy area is empty */ + if ((ySrc > yTop + cNumScan) || (ySrc + (INT)cy < yTop)) goto leave; + + /* Check if the copy area starts below or at the topmost scanline */ + if (ySrc >= yTop) + { + /* Compensate the source y-origin for the scanline offset */ + ySrc -= yTop; + } + else + { + /* Start at the top-most scanline in the buffer, adjust the destination + coordinates and crop the size accordingly. */ + yDst += (yTop - ySrc); + cy -= (yTop - ySrc); + ySrc = 0; + } + + /* Check if the DIB is top-down */ + if (pbmi->bmiHeader.biHeight < 0) + { + pbmi->bmiHeader.biHeight = -(LONG)cNumScan; + } + else + { + pbmi->bmiHeader.biHeight = cNumScan; + } + + /* Call the internal function with the secure pointers */ + iResult = GreStretchDIBitsInternal(hdcDest, + xDst, + yDst, + cx, + cy, + xSrc, + ySrc, + cx, + cy, + pjBits, + pbmi, + iUsage, + MAKEROP4(SRCCOPY, SRCCOPY), + cjMaxInfo, + cjMaxBits, + bTransformCoordinates, + hcmXform); + + /* Unsecure the memory */ + EngUnsecureMem(hSecure); + +leave: /* Free the bitmap info */ DibFreeBitmapInfo(pbmi);
@@ -1317,7 +1431,7 @@ _In_ DWORD dwRop, // ms ntgdi.h says dwRop4(?) _In_ UINT cjMaxInfo, _In_ UINT cjMaxBits, - _In_ HANDLE hcmXform) + _In_opt_ HANDLE hcmXform) { PBITMAPINFO pbmi; HANDLE hSecure;
Modified: branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.h URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/ntgdi/di... ============================================================================== --- branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.h [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/gdi/ntgdi/dibitmap.h [iso-8859-1] Tue Aug 14 22:27:00 2012 @@ -10,6 +10,8 @@ ULONG cBitsPixel; ULONG iCompression; ULONG iFormat; + ULONG cjWidthBytes; + ULONG cjImageSize; } BITMAPFORMAT, *PBITMAPFORMAT;
ULONG @@ -19,8 +21,16 @@ _In_ ULONG iUsage);
INT -NTAPI -GreGetDIBitsInternal( +APIENTRY +GreGetDIBitmapInfo( + _In_ HBITMAP hbm, + _Inout_ LPBITMAPINFO pbmi, + _In_ UINT iUsage, + _In_ UINT cjMaxInfo); + +INT +APIENTRY +GreGetDIBits( _In_ HDC hdc, _In_ HBITMAP hbm, _In_ UINT iStartScan, @@ -83,4 +93,87 @@ UINT Entries, RGBQUAD *Colors);
-#define DIB_BitmapInfoSize +W32KAPI +INT +APIENTRY +OldNtGdiSetDIBitsToDeviceInternal( + IN HDC hDC, + IN INT XDest, + IN INT YDest, + IN DWORD Width, + IN DWORD Height, + IN INT XSrc, + IN INT YSrc, + IN DWORD StartScan, + IN DWORD ScanLines, + IN LPBYTE Bits, + IN LPBITMAPINFO bmi, + IN DWORD ColorUse, + IN UINT cjMaxBits, + IN UINT cjMaxInfo, + IN BOOL bTransformCoordinates, + IN OPTIONAL HANDLE hcmXform); + +INT +APIENTRY +OldNtGdiGetDIBitsInternal( + HDC hDC, + HBITMAP hBitmap, + UINT StartScan, + UINT ScanLines, + LPBYTE Bits, + LPBITMAPINFO Info, + UINT Usage, + UINT MaxBits, + UINT MaxInfo); + +W32KAPI +INT +APIENTRY +OldNtGdiStretchDIBitsInternal( + IN HDC hdc, + IN INT xDst, + IN INT yDst, + IN INT cxDst, + IN INT cyDst, + IN INT xSrc, + IN INT ySrc, + IN INT cxSrc, + IN INT cySrc, + IN OPTIONAL LPBYTE pjInit, + IN LPBITMAPINFO pbmi, + IN DWORD dwUsage, + IN DWORD dwRop, // MS ntgdi.h says dwRop4(?) + IN UINT cjMaxInfo, + IN UINT cjMaxBits, + IN HANDLE hcmXform); + +HBITMAP +APIENTRY +OldNtGdiCreateDIBitmapInternal( + IN HDC hDc, + IN INT cx, + IN INT cy, + IN DWORD fInit, + IN OPTIONAL LPBYTE pjInit, + IN OPTIONAL LPBITMAPINFO pbmi, + IN DWORD iUsage, + IN UINT cjMaxInitInfo, + IN UINT cjMaxBits, + IN FLONG fl, + IN HANDLE hcmXform); + +HBITMAP +APIENTRY +OldNtGdiCreateDIBSection( + IN HDC hDC, + IN OPTIONAL HANDLE hSection, + IN DWORD dwOffset, + IN BITMAPINFO* bmi, + IN DWORD Usage, + IN UINT cjHeader, + IN FLONG fl, + IN ULONG_PTR dwColorSpace, + OUT PVOID *Bits); + +
Modified: branches/dib_rewrite/win32ss/gdi/ntgdi/dibobj.c URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/gdi/ntgdi/di... ============================================================================== --- branches/dib_rewrite/win32ss/gdi/ntgdi/dibobj.c [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/gdi/ntgdi/dibobj.c [iso-8859-1] Tue Aug 14 22:27:00 2012 @@ -10,6 +10,45 @@
#define NDEBUG #include <debug.h> + +#if 0 + +int +FASTCALL +DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width, + LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size ); + +HBITMAP +APIENTRY +DIB_CreateDIBSection( + PDC dc, + CONST BITMAPINFO *bmi, + UINT usage, + LPVOID *bits, + HANDLE section, + DWORD offset, + DWORD ovr_pitch); + +HBITMAP +NTAPI +OldGreCreateDIBitmapInternal( + IN HDC hDc, + IN INT cx, + IN INT cy, + IN DWORD fInit, + IN OPTIONAL LPBYTE pjInit, + IN OPTIONAL PBITMAPINFO pbmi, + IN DWORD iUsage, + IN FLONG fl, + IN UINT cjMaxBits, + IN HANDLE hcmXform); + +PPALETTE +NTAPI +CreateDIBPalette( + _In_ const BITMAPINFO *pbmi, + _In_ PDC pdc, + _In_ ULONG iUsage);
static const RGBQUAD EGAColorsQuads[16] = { @@ -105,7 +144,7 @@
PPALETTE NTAPI -CreateDIBPalette( +OldCreateDIBPalette( _In_ const BITMAPINFO *pbmi, _In_ PDC pdc, _In_ ULONG iUsage) @@ -378,7 +417,7 @@ W32KAPI INT APIENTRY -NtGdiSetDIBitsToDeviceInternal( +OldNtGdiSetDIBitsToDeviceInternal( IN HDC hDC, IN INT XDest, IN INT YDest, @@ -560,7 +599,7 @@ /* Converts a device-dependent bitmap to a DIB */ INT APIENTRY -NtGdiGetDIBitsInternal( +OldNtGdiGetDIBitsInternal( HDC hDC, HBITMAP hBitmap, UINT StartScan, @@ -1026,7 +1065,7 @@ W32KAPI INT APIENTRY -NtGdiStretchDIBitsInternal( +OldNtGdiStretchDIBitsInternal( IN HDC hdc, IN INT xDst, IN INT yDst, @@ -1269,7 +1308,7 @@ // The DDB that is created will be whatever bit depth your reference DC is HBITMAP APIENTRY -NtGdiCreateDIBitmapInternal( +OldNtGdiCreateDIBitmapInternal( IN HDC hDc, IN INT cx, IN INT cy, @@ -1318,7 +1357,7 @@ goto cleanup; }
- hbmResult = GreCreateDIBitmapInternal(hDc, + hbmResult = OldGreCreateDIBitmapInternal(hDc, cx, cy, fInit, @@ -1336,7 +1375,7 @@
HBITMAP NTAPI -GreCreateDIBitmapInternal( +OldGreCreateDIBitmapInternal( IN HDC hDc, IN INT cx, IN INT cy, @@ -1392,7 +1431,7 @@
HBITMAP APIENTRY -NtGdiCreateDIBSection( +OldNtGdiCreateDIBSection( IN HDC hDC, IN OPTIONAL HANDLE hSection, IN DWORD dwOffset, @@ -1695,7 +1734,7 @@ * 11/16/1999 (RJJ) lifted from wine */
-INT APIENTRY DIB_GetDIBImageBytes(INT width, INT height, INT depth) +INT APIENTRY OldDIB_GetDIBImageBytes(INT width, INT height, INT depth) { return WIDTH_BYTES_ALIGN32(width, depth) * (height < 0 ? -height : height); } @@ -1845,4 +1884,5 @@ ExFreePoolWithTag(converted, TAG_DIB); }
+#endif /* EOF */
Modified: branches/dib_rewrite/win32ss/user/ntuser/clipboard.c URL: http://svn.reactos.org/svn/reactos/branches/dib_rewrite/win32ss/user/ntuser/... ============================================================================== --- branches/dib_rewrite/win32ss/user/ntuser/clipboard.c [iso-8859-1] (original) +++ branches/dib_rewrite/win32ss/user/ntuser/clipboard.c [iso-8859-1] Tue Aug 14 22:27:00 2012 @@ -135,49 +135,68 @@ }
VOID static NTAPI -IntSynthesizeDib(PWINSTATION_OBJECT pWinStaObj, HBITMAP hBm) +IntSynthesizeDib( + PWINSTATION_OBJECT pWinStaObj, + HBITMAP hbm) { HDC hdc; - BITMAP bm; - BITMAPINFO bi; - SURFACE *psurf; - PCLIPBOARDDATA pMemObj; + BITMAPINFO bmi; + ULONG cjInfoSize, cjDataSize; + PCLIPBOARDDATA pClipboardData; HANDLE hMem; - + INT iResult; + + /* Get the display DC */ hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE); if (!hdc) + { return; - - // FIXME: use a less cheesy way to calculate the size of the bitmap! - - psurf = SURFACE_ShareLockSurface(hBm); - if (!psurf) - goto cleanup; - BITMAP_GetObject(psurf, sizeof(BITMAP), (PVOID)&bm); - SURFACE_ShareUnlockSurface(psurf); - - bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bi.bmiHeader.biWidth = bm.bmWidth; - bi.bmiHeader.biHeight = bm.bmHeight; - bi.bmiHeader.biPlanes = bm.bmPlanes; - bi.bmiHeader.biBitCount = bm.bmBitsPixel; - bi.bmiHeader.biCompression = BI_RGB; - bi.bmiHeader.biSizeImage = 0; - bi.bmiHeader.biXPelsPerMeter = 0; - bi.bmiHeader.biYPelsPerMeter = 0; - bi.bmiHeader.biClrUsed = 0; - - GreGetDIBitsInternal(hdc, hBm, 0, bm.bmHeight, NULL, &bi, DIB_RGB_COLORS, 0, 0); - - pMemObj = (PCLIPBOARDDATA)UserCreateObject(gHandleTable, NULL, &hMem, otClipBoardData, - sizeof(BITMAPINFOHEADER) + bi.bmiHeader.biSizeImage); - if(pMemObj) - { - pMemObj->cbData = sizeof(BITMAPINFOHEADER) + bi.bmiHeader.biSizeImage; - memcpy(pMemObj->Data, &bi, sizeof(BITMAPINFOHEADER)); - GreGetDIBitsInternal(hdc, hBm, 0, bm.bmHeight, (LPBYTE)pMemObj->Data + sizeof(BITMAPINFOHEADER), &bi, DIB_RGB_COLORS, 0, 0); - IntAddFormatedData(pWinStaObj, CF_DIB, hMem, TRUE, TRUE); - } + } + + /* Get information about the bitmap format */ + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + iResult = GreGetDIBitmapInfo(hbm, &bmi, DIB_RGB_COLORS, sizeof(bmi)); + if (iResult == 0) + { + goto cleanup; + } + + /* Get the size for a full BITMAPINFO */ + cjInfoSize = DibGetBitmapInfoSize(&bmi, DIB_RGB_COLORS); + + /* Calculate the size of the clipboard data, which is a packed DIB */ + cjDataSize = cjInfoSize + bmi.bmiHeader.biSizeImage; + + /* Create the clipboard data */ + pClipboardData = (PCLIPBOARDDATA)UserCreateObject(gHandleTable, + NULL, + &hMem, + otClipBoardData, + cjDataSize); + if (!pClipboardData) + { + goto cleanup; + } + + /* Set the data size */ + pClipboardData->cbData = cjDataSize; + + /* Copy the BITMAPINFOHEADER */ + memcpy(pClipboardData->Data, &bmi, sizeof(BITMAPINFOHEADER)); + + /* Get the bitmap bits and the color table */ + iResult = GreGetDIBits(hdc, + hbm, + 0, + abs(bmi.bmiHeader.biHeight), + (LPBYTE)pClipboardData->Data + cjInfoSize, + (LPBITMAPINFO)pClipboardData->Data, + DIB_RGB_COLORS, + bmi.bmiHeader.biSizeImage, + cjInfoSize); + + /* Add the clipboard data */ + IntAddFormatedData(pWinStaObj, CF_DIB, hMem, TRUE, TRUE);
cleanup: UserReleaseDC(NULL, hdc, FALSE); @@ -187,7 +206,7 @@ IntSynthesizeBitmap(PWINSTATION_OBJECT pWinStaObj, PCLIP pBmEl) { HDC hdc = NULL; - PBITMAPINFO pBmi, pConvertedBmi = NULL; + PBITMAPINFO pBmi; HBITMAP hBm = NULL; PCLIPBOARDDATA pMemObj; PCLIP pDibEl; @@ -204,27 +223,23 @@ if (!pMemObj) return;
- pBmi = (BITMAPINFO*)pMemObj->Data; + pBmi = (BITMAPINFO*)pMemObj->Data;
if (pMemObj->cbData < sizeof(DWORD) && pMemObj->cbData < pBmi->bmiHeader.biSize) goto cleanup;
- pConvertedBmi = DIB_ConvertBitmapInfo(pBmi, DIB_RGB_COLORS); - if (!pConvertedBmi) - goto cleanup; - - Offset = DIB_BitmapInfoSize(pBmi, DIB_RGB_COLORS); + Offset = DibGetBitmapInfoSize(pBmi, DIB_RGB_COLORS);
hdc = UserGetDCEx(NULL, NULL, DCX_USESTYLE); if (!hdc) goto cleanup;
hBm = GreCreateDIBitmapInternal(hdc, - pConvertedBmi->bmiHeader.biWidth, - pConvertedBmi->bmiHeader.biHeight, + pBmi->bmiHeader.biWidth, + pBmi->bmiHeader.biHeight, CBM_INIT, pMemObj->Data + Offset, - pConvertedBmi, + pBmi, DIB_RGB_COLORS, 0, pMemObj->cbData - Offset, @@ -240,9 +255,6 @@ cleanup: if (hdc) UserReleaseDC(NULL, hdc, FALSE); - - if (pConvertedBmi) - DIB_FreeConvertedBitmapInfo(pConvertedBmi, pBmi); }
VOID static NTAPI