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.…
==============================================================================
--- 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/bit…
==============================================================================
--- 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/o…
==============================================================================
--- 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/o…
==============================================================================
--- 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/b…
==============================================================================
--- 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/d…
==============================================================================
--- 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/d…
==============================================================================
--- 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/d…
==============================================================================
--- 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