Author: jimtabor
Date: Mon Nov 17 23:36:19 2008
New Revision: 37436
URL:
http://svn.reactos.org/svn/reactos?rev=37436&view=rev
Log:
- Fixes bug 3864. While I was at it I fixed most of the gdi max bit max info sizes too.
- Added notes for the SEH abuse in win32k dibobj.c.
- Tested WinMerge 2.10.2, AbiWord 2.4.1, Firefox 1.5.0.3 and wine gdi32 bitmap cross
test.
- When testing with gdi cross test in 24 and 32 bit display mode, we have a pixel
conversion mismatch. Please fix it!
Modified:
trunk/reactos/dll/win32/gdi32/include/gdi32p.h
trunk/reactos/dll/win32/gdi32/misc/stubs.c
trunk/reactos/dll/win32/gdi32/objects/bitmap.c
trunk/reactos/dll/win32/gdi32/objects/utils.c
trunk/reactos/subsystems/win32/win32k/include/dc.h
trunk/reactos/subsystems/win32/win32k/objects/dibobj.c
Modified: trunk/reactos/dll/win32/gdi32/include/gdi32p.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/include/gd…
==============================================================================
--- trunk/reactos/dll/win32/gdi32/include/gdi32p.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdi32/include/gdi32p.h [iso-8859-1] Mon Nov 17 23:36:19 2008
@@ -231,6 +231,7 @@
GdiSetLastError( DWORD dwErrCode );
DWORD STDCALL GdiGetCodePage(HDC);
+UINT FASTCALL DIB_BitmapBitsSize( PBITMAPINFO );
/* EOF */
Modified: trunk/reactos/dll/win32/gdi32/misc/stubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/misc/stubs…
==============================================================================
--- trunk/reactos/dll/win32/gdi32/misc/stubs.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdi32/misc/stubs.c [iso-8859-1] Mon Nov 17 23:36:19 2008
@@ -1789,28 +1789,6 @@
/*
* @unimplemented
*/
-HBITMAP STDCALL
-CreateBitmap(INT Width,
- INT Height,
- UINT Planes,
- UINT BitsPixel,
- PCVOID pUnsafeBits)
-{
- /* FIXME some part should be done in user mode */
- if (Width && Height)
- {
- return NtGdiCreateBitmap(Width, Height, Planes, BitsPixel, (LPBYTE)
pUnsafeBits);
- }
- else
- {
- /* Return 1x1 bitmap */
- return GetStockObject(DEFAULT_BITMAP);
- }
-}
-
-/*
- * @unimplemented
- */
ULONG STDCALL
XLATEOBJ_iXlate(XLATEOBJ *XlateObj,
ULONG Color)
Modified: trunk/reactos/dll/win32/gdi32/objects/bitmap.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/objects/bi…
==============================================================================
--- trunk/reactos/dll/win32/gdi32/objects/bitmap.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdi32/objects/bitmap.c [iso-8859-1] Mon Nov 17 23:36:19 2008
@@ -6,13 +6,15 @@
/*
* Return the full scan size for a bitmap.
*
- * Based on Wine, Utils.c and Windows Graphics Prog pg 595
+ * Based on Wine, Utils.c and Windows Graphics Prog pg 595, SDK amvideo.h.
*/
UINT
FASTCALL
DIB_BitmapMaxBitsSize( PBITMAPINFO Info, UINT ScanLines )
{
UINT MaxBits = 0;
+
+ if (!Info) return 0;
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
@@ -30,6 +32,33 @@
return (MaxBits * ScanLines); // ret the full Size.
}
+UINT
+FASTCALL
+DIB_BitmapBitsSize( PBITMAPINFO Info )
+{
+ UINT Ret;
+
+ if (!Info) return 0;
+
+ if ( Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
+ {
+ PBITMAPCOREHEADER Core = (PBITMAPCOREHEADER)Info;
+ Ret = Core->bcHeight *
+ ((Core->bcWidth * Core->bcPlanes * Core->bcBitCount + 31) & ~31 )
/ 8;
+ }
+ else /* assume BITMAPINFOHEADER */
+ {
+ if ((Info->bmiHeader.biCompression) &&
+ (Info->bmiHeader.biCompression != BI_BITFIELDS))
+ return Info->bmiHeader.biSizeImage;
+ // Make Height positive always....
+ Ret = abs(Info->bmiHeader.biHeight) *
+ ((Info->bmiHeader.biWidth * Info->bmiHeader.biPlanes *
Info->bmiHeader.biBitCount + 31) & ~31 ) / 8;
+ }
+ return Ret;
+}
+
+
/*
* DIB_GetBitmapInfo is complete copy of wine cvs 2/9-2006
* from file dib.c from gdi32.dll or orginal version
@@ -111,15 +140,41 @@
PBITMAPINFO pConvertedInfo;
UINT ConvertedInfoSize;
HBITMAP hBitmap = NULL;
+ PVOID bmBits = NULL;
pConvertedInfo = ConvertBitmapInfo(BitmapInfo, Usage,
&ConvertedInfoSize, FALSE);
if (pConvertedInfo)
- {
- hBitmap = NtGdiCreateDIBSection(hDC, hSection, dwOffset, pConvertedInfo, Usage, 0,
0, 0, Bits);
+ { // Verify header due to converted may == info.
+ if ( pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
+ {
+ if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
+ pConvertedInfo->bmiHeader.biCompression == BI_PNG )
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+ }
+ bmBits = Bits;
+ hBitmap = NtGdiCreateDIBSection( hDC,
+ hSection,
+ dwOffset,
+ pConvertedInfo,
+ Usage,
+ 0,
+ 0,
+ 0,
+ &bmBits);
if (BitmapInfo != pConvertedInfo)
RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
+
+ if (!hBitmap)
+ {
+ bmBits = NULL;
+ }
}
+
+ if (Bits) *Bits = bmBits;
return hBitmap;
}
@@ -191,6 +246,28 @@
}
/*
+ * @unimplemented
+ */
+HBITMAP STDCALL
+CreateBitmap(INT Width,
+ INT Height,
+ UINT Planes,
+ UINT BitsPixel,
+ PCVOID pUnsafeBits)
+{
+ /* FIXME some part should be done in user mode */
+ if (Width && Height)
+ {
+ return NtGdiCreateBitmap(Width, Height, Planes, BitsPixel, (LPBYTE)
pUnsafeBits);
+ }
+ else
+ {
+ /* Return 1x1 bitmap */
+ return GetStockObject(DEFAULT_BITMAP);
+ }
+}
+
+/*
* @implemented
*/
HBITMAP WINAPI
@@ -234,9 +311,35 @@
INT Width,
INT Height)
{
- /* FIXME some part shall be done in user mode */
- return NtGdiCreateCompatibleBitmap(hDC, Width, Height);
-}
+ PDC_ATTR pDc_Attr;
+ HBITMAP hBmp = NULL;
+ DIBSECTION dibs;
+
+ if (!GdiGetHandleUserData(hDC, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
+ return NULL;
+
+ if ( !Width || !Height )
+ return GetStockObject(DEFAULT_BITMAP);
+
+ if (!(pDc_Attr->ulDirty_ & DC_DIBSECTION))
+ {
+ return NtGdiCreateCompatibleBitmap(hDC, Width, Height);
+ }
+
+ hBmp = NtGdiGetDCObject(hDC, GDI_OBJECT_TYPE_BITMAP);
+
+ if ( GetObjectA(hBmp, sizeof(DIBSECTION), &dibs) != sizeof(DIBSECTION) )
+ return NULL;
+
+ if ( dibs.dsBm.bmBitsPixel <= 8 )
+ GetDIBColorTable(hDC, 0, 256, (RGBQUAD *)&dibs.dsBitfields);
+
+ dibs.dsBmih.biWidth = Width;
+ dibs.dsBmih.biHeight = Height;
+
+ return CreateDIBSection(hDC, (CONST BITMAPINFO *)&dibs.dsBmih, 0, NULL, NULL, 0);
+}
+
@@ -251,34 +354,50 @@
LPBITMAPINFO lpbmi,
UINT uUsage)
{
- INT ret = 0;
-
- if (hDC == NULL || !GdiIsHandleValid((HGDIOBJ)hDC))
- {
- GdiSetLastError(ERROR_INVALID_PARAMETER);
- }
- else if (lpbmi == NULL)
- {
- // XP doesn't run this check and results in a
- // crash in DIB_BitmapMaxBitsSize, we'll be more forgiving
- GdiSetLastError(ERROR_INVALID_PARAMETER);
- }
- else
- {
- UINT cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines);
-
- ret = NtGdiGetDIBitsInternal(hDC,
- hbmp,
- uStartScan,
- cScanLines,
- lpvBits,
- lpbmi,
- uUsage,
- cjBmpScanSize,
- 0);
- }
-
- return ret;
+ 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 )
+ {
+ if ( lpbmi->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
+ {
+ if ( lpbmi->bmiHeader.biCompression == BI_JPEG ||
+ lpbmi->bmiHeader.biCompression == BI_PNG )
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return Ret;
+ }
+ }
+ }
+ pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize);
+ }
+
+ Ret = NtGdiGetDIBitsInternal(hDC,
+ hbmp,
+ uStartScan,
+ cScanLines,
+ pvSafeBits,
+ lpbmi,
+ uUsage,
+ cjBmpScanSize,
+ 0);
+ if ( lpvBits )
+ {
+ RtlCopyMemory( lpvBits, pvSafeBits, cjBmpScanSize);
+ RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
+ }
+ return Ret;
}
/*
@@ -293,26 +412,73 @@
const BITMAPINFO *Data,
UINT ColorUse)
{
- LONG width, height, compr, dibsize;
- WORD planes, bpp;
-
- if (DIB_GetBitmapInfo(Header, &width, &height, &planes, &bpp,
&compr, &dibsize) == -1)
- {
- GdiSetLastError(ERROR_INVALID_PARAMETER);
- return NULL;
- }
-
- return NtGdiCreateDIBitmapInternal(hDC,
- width,
- height,
- Init,
- (LPBYTE)Bits,
- (PBITMAPINFO)Data,
- ColorUse,
- bpp,
- dibsize,
- 0,
- 0);
+ LONG width, height, compr, dibsize;
+ WORD planes, bpp;
+// PDC_ATTR pDc_Attr;
+ PBITMAPINFO pConvertedInfo;
+ UINT ConvertedInfoSize;
+ UINT cjBmpScanSize;
+ PVOID pvSafeBits = NULL;
+ HBITMAP hBmp;
+
+ pConvertedInfo = ConvertBitmapInfo(Data, ColorUse,
+ &ConvertedInfoSize, FALSE);
+
+ if (DIB_GetBitmapInfo(Header, &width, &height, &planes, &bpp,
&compr, &dibsize) == -1)
+ {
+ GdiSetLastError(ERROR_INVALID_PARAMETER);
+ return NULL;
+ }
+
+ if ( pConvertedInfo )
+ {
+ if ( pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
+ {
+ if ( pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
+ pConvertedInfo->bmiHeader.biCompression == BI_PNG )
+ {
+ hBmp = NULL;
+ goto Exit;
+ }
+ }
+ }
+
+// For Icm support.
+// GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
+
+ cjBmpScanSize = DIB_BitmapBitsSize((LPBITMAPINFO)pConvertedInfo);
+ DPRINT("pBMI %x, Size bpp %d, dibsize %d, Conv %d, BSS %d\n",
pConvertedInfo,bpp,dibsize,ConvertedInfoSize,cjBmpScanSize);
+
+ if ( !width || !height )
+ hBmp = GetStockObject(DEFAULT_BITMAP);
+ else
+ {
+ if ( Bits )
+ {
+ pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize);
+ if ( pvSafeBits )
+ RtlCopyMemory( pvSafeBits, Bits, cjBmpScanSize);
+ }
+
+ hBmp = NtGdiCreateDIBitmapInternal(hDC,
+ width,
+ height,
+ Init,
+ (LPBYTE)pvSafeBits,
+ (PBITMAPINFO)pConvertedInfo,
+ ColorUse,
+ ConvertedInfoSize,
+ cjBmpScanSize,
+ 0,
+ 0);
+
+ if ( Bits )
+ RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
+ }
+Exit:
+ if (Data != pConvertedInfo)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
+ return hBmp;
}
#if 0 // FIXME!!! This is a victim of the Win32k Initialization BUG!!!!!
@@ -419,7 +585,25 @@
CONST BITMAPINFO *lpbmi,
UINT fuColorUse)
{
- return NtGdiSetDIBits(hdc, hbmp, uStartScan, cScanLines, lpvBits, lpbmi, fuColorUse);
+ INT LinesCopied = 0;
+
+// This needs to be almost the sames as SetDIBitsToDevice
+
+ if ( !cScanLines || !lpbmi || !lpvBits || (GDI_HANDLE_GET_TYPE(hbmp) !=
GDI_OBJECT_TYPE_BITMAP))
+ return 0;
+
+ if ( fuColorUse && fuColorUse != DIB_PAL_COLORS && fuColorUse !=
DIB_PAL_COLORS+1 )
+ return 0;
+
+ LinesCopied = NtGdiSetDIBits( hdc,
+ hbmp,
+ uStartScan,
+ cScanLines,
+ lpvBits,
+ lpbmi,
+ fuColorUse);
+
+ return LinesCopied;
}
/*
@@ -429,7 +613,7 @@
INT
STDCALL
SetDIBitsToDevice(
- HDC hDC,
+ HDC hdc,
int XDest,
int YDest,
DWORD Width,
@@ -442,22 +626,111 @@
CONST BITMAPINFO *lpbmi,
UINT ColorUse)
{
- return NtGdiSetDIBitsToDeviceInternal(hDC,
- XDest,
- YDest,
- Width,
- Height,
- XSrc,
- YSrc,
- StartScan,
- ScanLines,
- (LPBYTE)Bits,
- (LPBITMAPINFO)lpbmi,
- ColorUse,
- lpbmi->bmiHeader.biSizeImage,
- lpbmi->bmiHeader.biSize,
- TRUE,
- NULL);
+ PDC_ATTR pDc_Attr;
+ PBITMAPINFO pConvertedInfo;
+ UINT ConvertedInfoSize;
+ INT LinesCopied = 0;
+ UINT cjBmpScanSize = 0;
+ PVOID pvSafeBits = (PVOID)Bits;
+
+ if ( !ScanLines || !lpbmi || !Bits )
+ return 0;
+
+ if ( ColorUse && ColorUse != DIB_PAL_COLORS && ColorUse !=
DIB_PAL_COLORS+1 )
+ return 0;
+
+ pConvertedInfo = ConvertBitmapInfo(lpbmi, ColorUse,
+ &ConvertedInfoSize, FALSE);
+ if (!pConvertedInfo)
+ return 0;
+
+#if 0
+// Handle something other than a normal dc object.
+ if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
+ {
+ if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
+ return MFDRV_SetDIBitsToDevice( hdc,
+ XDest,
+ YDest,
+ Width,
+ Height,
+ XSrc,
+ YSrc,
+ StartScan,
+ ScanLines,
+ Bits,
+ lpbmi,
+ ColorUse);
+ else
+ {
+ PLDC pLDC = GdiGetLDC(hdc);
+ if ( !pLDC )
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+ if (pLDC->iType == LDC_EMFLDC)
+ {
+ return EMFDRV_SetDIBitsToDevice(hdc,
+ XDest,
+ YDest,
+ Width,
+ Height,
+ XSrc,
+ YSrc,
+ StartScan,
+ ScanLines,
+ Bits,
+ lpbmi,
+ ColorUse);
+ }
+ return 0;
+ }
+ }
+#endif
+ cjBmpScanSize = DIB_BitmapMaxBitsSize((LPBITMAPINFO)lpbmi, ScanLines);
+
+ if ( Bits )
+ {
+ pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize);
+ if (pvSafeBits)
+ RtlCopyMemory( pvSafeBits, Bits, cjBmpScanSize);
+ }
+
+ if (!GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+/*
+ if ( !pDc_Attr ||
+ ((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
+ (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
+ pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/
+ {
+ LinesCopied = NtGdiSetDIBitsToDeviceInternal( hdc,
+ XDest,
+ YDest,
+ Width,
+ Height,
+ XSrc,
+ YSrc,
+ StartScan,
+ ScanLines,
+ (LPBYTE)pvSafeBits,
+ (LPBITMAPINFO)pConvertedInfo,
+ ColorUse,
+ cjBmpScanSize,
+ ConvertedInfoSize,
+ TRUE,
+ NULL);
+ }
+ if ( Bits )
+ RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
+ if (lpbmi != pConvertedInfo)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
+
+ return LinesCopied;
}
@@ -481,9 +754,133 @@
DWORD dwRop)
{
- DPRINT("StretchDIBits %x : %x\n", lpBits, lpBitsInfo);
- /* FIXME share memory */
- return NtGdiStretchDIBitsInternal(hdc, XDest, YDest, nDestWidth, nDestHeight, XSrc,
YSrc,
- nSrcWidth, nSrcHeight, (LPBYTE)lpBits,
(LPBITMAPINFO)lpBitsInfo, (DWORD)iUsage, dwRop, 0, 0, NULL);
-}
-
+ PDC_ATTR pDc_Attr;
+ PBITMAPINFO pConvertedInfo = NULL;
+ UINT ConvertedInfoSize = 0;
+ INT LinesCopied = 0;
+ UINT cjBmpScanSize = 0;
+ PVOID pvSafeBits = NULL;
+ BOOL Hit = FALSE;
+
+ DPRINT("StretchDIBits %x : %x : %d\n", lpBits, lpBitsInfo, iUsage);
+#if 0
+// Handle something other than a normal dc object.
+ if (GDI_HANDLE_GET_TYPE(hdc) != GDI_OBJECT_TYPE_DC)
+ {
+ if (GDI_HANDLE_GET_TYPE(hdc) == GDI_OBJECT_TYPE_METADC)
+ return MFDRV_StretchBlt( hdc,
+ XDest,
+ YDest,
+ nDestWidth,
+ nDestHeight,
+ XSrc,
+ YSrc,
+ nSrcWidth,
+ nSrcHeight,
+ lpBits,
+ lpBitsInfo,
+ iUsage,
+ dwRop);
+ else
+ {
+ PLDC pLDC = GdiGetLDC(hdc);
+ if ( !pLDC )
+ {
+ SetLastError(ERROR_INVALID_HANDLE);
+ return 0;
+ }
+ if (pLDC->iType == LDC_EMFLDC)
+ {
+ return EMFDRV_StretchBlt(hdc,
+ XDest,
+ YDest,
+ nDestWidth,
+ nDestHeight,
+ XSrc,
+ YSrc,
+ nSrcWidth,
+ nSrcHeight,
+ lpBits,
+ lpBitsInfo,
+ iUsage,
+ dwRop);
+ }
+ return 0;
+ }
+ }
+#endif
+ if ( iUsage ) // Save time, we only look at non RGB.
+ {
+ pConvertedInfo = ConvertBitmapInfo(lpBitsInfo, iUsage,
+ &ConvertedInfoSize, FALSE);
+ if (!pConvertedInfo)
+ {
+ return 0;
+ }
+ }
+ else
+ pConvertedInfo = (PBITMAPINFO)lpBitsInfo;
+
+ cjBmpScanSize = DIB_BitmapBitsSize((LPBITMAPINFO)pConvertedInfo);
+
+ if ( lpBits )
+ {
+ pvSafeBits = RtlAllocateHeap(GetProcessHeap(), 0, cjBmpScanSize);
+ if (pvSafeBits)
+ {
+ _SEH_TRY
+ {
+ RtlCopyMemory( pvSafeBits, lpBits, cjBmpScanSize );
+ }
+ _SEH_HANDLE
+ {
+ Hit = TRUE;
+ }
+ _SEH_END
+
+ if (Hit)
+ {
+ // We don't die, we continue on with a allocated safe pointer to kernel
+ // space.....
+ DPRINT1("StretchDIBits fail to read BitMapInfo: %x or Bits: %x &
Size: %d\n",pConvertedInfo,lpBits,cjBmpScanSize);
+ }
+ DPRINT("StretchDIBits Allocate Bits %d!!!\n", cjBmpScanSize);
+ }
+ }
+
+ if (!GdiGetHandleUserData(hdc, GDI_OBJECT_TYPE_DC, (PVOID)&pDc_Attr))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+/*
+ if ( !pDc_Attr ||
+ ((pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER)) &&
+ (pConvertedInfo->bmiHeader.biCompression == BI_JPEG ||
+ pConvertedInfo->bmiHeader.biCompression == BI_PNG )) )*/
+ {
+ LinesCopied = NtGdiStretchDIBitsInternal( hdc,
+ XDest,
+ YDest,
+ nDestWidth,
+ nDestHeight,
+ XSrc,
+ YSrc,
+ nSrcWidth,
+ nSrcHeight,
+ pvSafeBits,
+ pConvertedInfo,
+ (DWORD)iUsage,
+ dwRop,
+ ConvertedInfoSize,
+ cjBmpScanSize,
+ NULL);
+ }
+ if ( pvSafeBits )
+ RtlFreeHeap(RtlGetProcessHeap(), 0, pvSafeBits);
+ if (lpBitsInfo != pConvertedInfo)
+ RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
+
+ return LinesCopied;
+}
+
Modified: trunk/reactos/dll/win32/gdi32/objects/utils.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/gdi32/objects/ut…
==============================================================================
--- trunk/reactos/dll/win32/gdi32/objects/utils.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/gdi32/objects/utils.c [iso-8859-1] Mon Nov 17 23:36:19 2008
@@ -214,32 +214,7 @@
if (FollowedByData)
{
- if (BitmapInfo->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
- {
- DataSize =
- CoreBitmapInfo->bmciHeader.bcHeight *
- CoreBitmapInfo->bmciHeader.bcWidth *
- CoreBitmapInfo->bmciHeader.bcBitCount;
- DataSize = ((DataSize + 31) & ~31) / 8;
- DataSize *= CoreBitmapInfo->bmciHeader.bcPlanes;
- }
- else
- {
- if (BitmapInfo->bmiHeader.biCompression == BI_RGB ||
- BitmapInfo->bmiHeader.biCompression == BI_BITFIELDS)
- {
- DataSize =
- abs(BitmapInfo->bmiHeader.biHeight) *
- BitmapInfo->bmiHeader.biWidth *
- BitmapInfo->bmiHeader.biBitCount;
- DataSize = ((DataSize + 31) & ~31) / 8;
- DataSize *= BitmapInfo->bmiHeader.biPlanes;
- }
- else
- {
- DataSize = BitmapInfo->bmiHeader.biSizeImage;
- }
- }
+ DataSize = DIB_BitmapBitsSize((PBITMAPINFO)BitmapInfo );
}
/*
Modified: trunk/reactos/subsystems/win32/win32k/include/dc.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/in…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/include/dc.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/include/dc.h [iso-8859-1] Mon Nov 17 23:36:19
2008
@@ -270,6 +270,7 @@
VOID FASTCALL IntvGetDeviceCaps(PGDIDEVICE, PDEVCAPS);
HPEN FASTCALL IntGdiSelectPen(PDC,HPEN);
HBRUSH FASTCALL IntGdiSelectBrush(PDC,HBRUSH);
+INT FASTCALL IntGdiGetDeviceCaps(PDC,INT);
extern PGDIDEVICE pPrimarySurface;
Modified: trunk/reactos/subsystems/win32/win32k/objects/dibobj.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/dibobj.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/dibobj.c [iso-8859-1] Mon Nov 17
23:36:19 2008
@@ -317,7 +317,7 @@
DC_UnlockDc(Dc);
return 0;
}
-
+ // Need SEH to check Bits and bmi. BTW bmi was converted in gdi.
Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
DC_UnlockDc(Dc);
@@ -399,7 +399,7 @@
ptSource.y = YSrc;
/* Enter SEH, as the bits are user mode */
- _SEH_TRY
+ _SEH_TRY // Look at NtGdiStretchDIBitsInternal
{
SourceSize.cx = bmi->bmiHeader.biWidth;
SourceSize.cy = ScanLines;
@@ -541,8 +541,8 @@
/* fill out the BITMAPINFO struct */
if (Bits == NULL)
{
- _SEH_TRY
- {
+ _SEH_TRY // Look at NtGdiStretchDIBitsInternal
+ { // Why check for anything, we converted in gdi!
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
@@ -806,10 +806,28 @@
HDC hdcMem;
HPALETTE hPal = NULL;
PDC pDC;
+ BOOL Hit = FALSE;
if (!Bits || !BitsInfo)
{
SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ _SEH_TRY
+ {
+ ProbeForRead(BitsInfo, cjMaxInfo, 1);
+ ProbeForRead(Bits, cjMaxBits, 1);
+ }
+ _SEH_HANDLE
+ {
+ Hit = TRUE;
+ }
+ _SEH_END
+
+ if (Hit)
+ {
+ DPRINT1("NtGdiStretchDIBitsInternal fail to read BitMapInfo: %x or Bits:
%x\n",BitsInfo,Bits);
return 0;
}
@@ -993,6 +1011,7 @@
{
PDC Dc;
HBITMAP Bmp;
+ UINT bpp;
if (!hDc)
{ // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
@@ -1010,9 +1029,8 @@
SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
}
-
- cjMaxInitInfo = 1;
- Bmp = IntCreateDIBitmap(Dc, cx, cy, cjMaxInitInfo, fInit, pjInit, pbmi, iUsage);
+ bpp = IntGdiGetDeviceCaps(Dc, BITSPIXEL);
+ Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
DC_UnlockDc(Dc);
NtGdiDeleteObjectApp(hDc);
@@ -1025,8 +1043,16 @@
SetLastWin32Error(ERROR_INVALID_HANDLE);
return NULL;
}
-
- Bmp = IntCreateDIBitmap(Dc, cx, cy, cjMaxInitInfo, fInit, pjInit, pbmi, iUsage);
+ /* pbmi == null
+ First create an un-initialised bitmap. The depth of the bitmap
+ should match that of the hdc and not that supplied in bmih.
+ */
+ if (pbmi)
+ bpp = pbmi->bmiHeader.biBitCount;
+ else
+ bpp = IntGdiGetDeviceCaps(Dc, BITSPIXEL);
+
+ Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
DC_UnlockDc(Dc);
}
return Bmp;