mirror of
https://github.com/reactos/reactos.git
synced 2025-06-06 01:40:36 +00:00
- 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! svn path=/trunk/; revision=37436
This commit is contained in:
parent
3595d1c30e
commit
fa0375352f
6 changed files with 504 additions and 126 deletions
|
@ -231,6 +231,7 @@ STDCALL
|
|||
GdiSetLastError( DWORD dwErrCode );
|
||||
|
||||
DWORD STDCALL GdiGetCodePage(HDC);
|
||||
UINT FASTCALL DIB_BitmapBitsSize( PBITMAPINFO );
|
||||
|
||||
/* EOF */
|
||||
|
||||
|
|
|
@ -1786,28 +1786,6 @@ CombineRgn(HRGN hDest,
|
|||
return NtGdiCombineRgn(hDest, hSrc1, hSrc2, CombineMode);
|
||||
}
|
||||
|
||||
/*
|
||||
* @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
|
||||
*/
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
/*
|
||||
* 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
|
||||
|
@ -14,6 +14,8 @@ DIB_BitmapMaxBitsSize( PBITMAPINFO Info, UINT ScanLines )
|
|||
{
|
||||
UINT MaxBits = 0;
|
||||
|
||||
if (!Info) return 0;
|
||||
|
||||
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||
{
|
||||
PBITMAPCOREHEADER Core = (PBITMAPCOREHEADER)Info;
|
||||
|
@ -30,6 +32,33 @@ DIB_BitmapMaxBitsSize( PBITMAPINFO Info, UINT ScanLines )
|
|||
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,16 +140,42 @@ CreateDIBSection(
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -190,6 +245,28 @@ StretchBlt(
|
|||
nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, dwRop, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* @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
|
||||
*/
|
||||
|
@ -234,12 +311,38 @@ CreateCompatibleBitmap(
|
|||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
INT
|
||||
STDCALL
|
||||
GetDIBits(
|
||||
|
@ -251,34 +354,50 @@ GetDIBits(
|
|||
LPBITMAPINFO lpbmi,
|
||||
UINT uUsage)
|
||||
{
|
||||
INT ret = 0;
|
||||
INT Ret = 0;
|
||||
UINT cjBmpScanSize;
|
||||
PVOID pvSafeBits = lpvBits;
|
||||
|
||||
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);
|
||||
if (!hDC || !GdiIsHandleValid((HGDIOBJ)hDC))
|
||||
{
|
||||
GdiSetLastError(ERROR_INVALID_PARAMETER);
|
||||
return Ret;
|
||||
}
|
||||
|
||||
ret = NtGdiGetDIBitsInternal(hDC,
|
||||
hbmp,
|
||||
uStartScan,
|
||||
cScanLines,
|
||||
lpvBits,
|
||||
lpbmi,
|
||||
uUsage,
|
||||
cjBmpScanSize,
|
||||
0);
|
||||
}
|
||||
cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines);
|
||||
|
||||
return ret;
|
||||
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 @@ CreateDIBitmap( HDC hDC,
|
|||
const BITMAPINFO *Data,
|
||||
UINT ColorUse)
|
||||
{
|
||||
LONG width, height, compr, dibsize;
|
||||
WORD planes, bpp;
|
||||
LONG width, height, compr, dibsize;
|
||||
WORD planes, bpp;
|
||||
// PDC_ATTR pDc_Attr;
|
||||
PBITMAPINFO pConvertedInfo;
|
||||
UINT ConvertedInfoSize;
|
||||
UINT cjBmpScanSize;
|
||||
PVOID pvSafeBits = NULL;
|
||||
HBITMAP hBmp;
|
||||
|
||||
if (DIB_GetBitmapInfo(Header, &width, &height, &planes, &bpp, &compr, &dibsize) == -1)
|
||||
{
|
||||
GdiSetLastError(ERROR_INVALID_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
pConvertedInfo = ConvertBitmapInfo(Data, ColorUse,
|
||||
&ConvertedInfoSize, FALSE);
|
||||
|
||||
return NtGdiCreateDIBitmapInternal(hDC,
|
||||
width,
|
||||
height,
|
||||
Init,
|
||||
(LPBYTE)Bits,
|
||||
(PBITMAPINFO)Data,
|
||||
ColorUse,
|
||||
bpp,
|
||||
dibsize,
|
||||
0,
|
||||
0);
|
||||
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 @@ SetDIBits(HDC hdc,
|
|||
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 @@ SetDIBits(HDC hdc,
|
|||
INT
|
||||
STDCALL
|
||||
SetDIBitsToDevice(
|
||||
HDC hDC,
|
||||
HDC hdc,
|
||||
int XDest,
|
||||
int YDest,
|
||||
DWORD Width,
|
||||
|
@ -442,22 +626,111 @@ SetDIBitsToDevice(
|
|||
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 @@ StretchDIBits(HDC hdc,
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -214,32 +214,7 @@ ConvertBitmapInfo(
|
|||
|
||||
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 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -270,6 +270,7 @@ BOOL FASTCALL IntGdiCleanDC(HDC hDC);
|
|||
VOID FASTCALL IntvGetDeviceCaps(PGDIDEVICE, PDEVCAPS);
|
||||
HPEN FASTCALL IntGdiSelectPen(PDC,HPEN);
|
||||
HBRUSH FASTCALL IntGdiSelectBrush(PDC,HBRUSH);
|
||||
INT FASTCALL IntGdiGetDeviceCaps(PDC,INT);
|
||||
|
||||
extern PGDIDEVICE pPrimarySurface;
|
||||
|
||||
|
|
|
@ -317,7 +317,7 @@ NtGdiSetDIBits(
|
|||
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 @@ NtGdiSetDIBitsToDeviceInternal(
|
|||
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 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
|||
/* 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,6 +806,7 @@ NtGdiStretchDIBitsInternal(
|
|||
HDC hdcMem;
|
||||
HPALETTE hPal = NULL;
|
||||
PDC pDC;
|
||||
BOOL Hit = FALSE;
|
||||
|
||||
if (!Bits || !BitsInfo)
|
||||
{
|
||||
|
@ -813,6 +814,23 @@ NtGdiStretchDIBitsInternal(
|
|||
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;
|
||||
}
|
||||
|
||||
hdcMem = NtGdiCreateCompatibleDC(hDC);
|
||||
if (hdcMem == NULL)
|
||||
{
|
||||
|
@ -993,6 +1011,7 @@ NtGdiCreateDIBitmapInternal(IN HDC hDc,
|
|||
{
|
||||
PDC Dc;
|
||||
HBITMAP Bmp;
|
||||
UINT bpp;
|
||||
|
||||
if (!hDc)
|
||||
{ // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
|
||||
|
@ -1010,9 +1029,8 @@ NtGdiCreateDIBitmapInternal(IN HDC hDc,
|
|||
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 @@ NtGdiCreateDIBitmapInternal(IN HDC hDc,
|
|||
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||
return NULL;
|
||||
}
|
||||
/* 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, cjMaxInitInfo, fInit, pjInit, pbmi, iUsage);
|
||||
Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
|
||||
DC_UnlockDc(Dc);
|
||||
}
|
||||
return Bmp;
|
||||
|
|
Loading…
Reference in a new issue