mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 15:46:52 +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 );
|
GdiSetLastError( DWORD dwErrCode );
|
||||||
|
|
||||||
DWORD STDCALL GdiGetCodePage(HDC);
|
DWORD STDCALL GdiGetCodePage(HDC);
|
||||||
|
UINT FASTCALL DIB_BitmapBitsSize( PBITMAPINFO );
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
||||||
|
|
|
@ -1786,28 +1786,6 @@ CombineRgn(HRGN hDest,
|
||||||
return NtGdiCombineRgn(hDest, hSrc1, hSrc2, CombineMode);
|
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
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
/*
|
/*
|
||||||
* Return the full scan size for a bitmap.
|
* 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
|
UINT
|
||||||
FASTCALL
|
FASTCALL
|
||||||
|
@ -14,6 +14,8 @@ DIB_BitmapMaxBitsSize( PBITMAPINFO Info, UINT ScanLines )
|
||||||
{
|
{
|
||||||
UINT MaxBits = 0;
|
UINT MaxBits = 0;
|
||||||
|
|
||||||
|
if (!Info) return 0;
|
||||||
|
|
||||||
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||||
{
|
{
|
||||||
PBITMAPCOREHEADER Core = (PBITMAPCOREHEADER)Info;
|
PBITMAPCOREHEADER Core = (PBITMAPCOREHEADER)Info;
|
||||||
|
@ -30,6 +32,33 @@ DIB_BitmapMaxBitsSize( PBITMAPINFO Info, UINT ScanLines )
|
||||||
return (MaxBits * ScanLines); // ret the full Size.
|
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
|
* DIB_GetBitmapInfo is complete copy of wine cvs 2/9-2006
|
||||||
* from file dib.c from gdi32.dll or orginal version
|
* from file dib.c from gdi32.dll or orginal version
|
||||||
|
@ -111,16 +140,42 @@ CreateDIBSection(
|
||||||
PBITMAPINFO pConvertedInfo;
|
PBITMAPINFO pConvertedInfo;
|
||||||
UINT ConvertedInfoSize;
|
UINT ConvertedInfoSize;
|
||||||
HBITMAP hBitmap = NULL;
|
HBITMAP hBitmap = NULL;
|
||||||
|
PVOID bmBits = NULL;
|
||||||
|
|
||||||
pConvertedInfo = ConvertBitmapInfo(BitmapInfo, Usage,
|
pConvertedInfo = ConvertBitmapInfo(BitmapInfo, Usage,
|
||||||
&ConvertedInfoSize, FALSE);
|
&ConvertedInfoSize, FALSE);
|
||||||
if (pConvertedInfo)
|
if (pConvertedInfo)
|
||||||
{
|
{ // Verify header due to converted may == info.
|
||||||
hBitmap = NtGdiCreateDIBSection(hDC, hSection, dwOffset, pConvertedInfo, Usage, 0, 0, 0, Bits);
|
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)
|
if (BitmapInfo != pConvertedInfo)
|
||||||
RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
|
RtlFreeHeap(RtlGetProcessHeap(), 0, pConvertedInfo);
|
||||||
|
|
||||||
|
if (!hBitmap)
|
||||||
|
{
|
||||||
|
bmBits = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Bits) *Bits = bmBits;
|
||||||
|
|
||||||
return hBitmap;
|
return hBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,6 +245,28 @@ StretchBlt(
|
||||||
nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, dwRop, 0, 0);
|
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
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -234,12 +311,38 @@ CreateCompatibleBitmap(
|
||||||
INT Width,
|
INT Width,
|
||||||
INT Height)
|
INT Height)
|
||||||
{
|
{
|
||||||
/* FIXME some part shall be done in user mode */
|
PDC_ATTR pDc_Attr;
|
||||||
return NtGdiCreateCompatibleBitmap(hDC, Width, Height);
|
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
|
INT
|
||||||
STDCALL
|
STDCALL
|
||||||
GetDIBits(
|
GetDIBits(
|
||||||
|
@ -251,34 +354,50 @@ GetDIBits(
|
||||||
LPBITMAPINFO lpbmi,
|
LPBITMAPINFO lpbmi,
|
||||||
UINT uUsage)
|
UINT uUsage)
|
||||||
{
|
{
|
||||||
INT ret = 0;
|
INT Ret = 0;
|
||||||
|
UINT cjBmpScanSize;
|
||||||
|
PVOID pvSafeBits = lpvBits;
|
||||||
|
|
||||||
if (hDC == NULL || !GdiIsHandleValid((HGDIOBJ)hDC))
|
if (!hDC || !GdiIsHandleValid((HGDIOBJ)hDC))
|
||||||
{
|
{
|
||||||
GdiSetLastError(ERROR_INVALID_PARAMETER);
|
GdiSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
}
|
return Ret;
|
||||||
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,
|
cjBmpScanSize = DIB_BitmapMaxBitsSize(lpbmi, cScanLines);
|
||||||
hbmp,
|
|
||||||
uStartScan,
|
|
||||||
cScanLines,
|
|
||||||
lpvBits,
|
|
||||||
lpbmi,
|
|
||||||
uUsage,
|
|
||||||
cjBmpScanSize,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
|
|
||||||
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,
|
const BITMAPINFO *Data,
|
||||||
UINT ColorUse)
|
UINT ColorUse)
|
||||||
{
|
{
|
||||||
LONG width, height, compr, dibsize;
|
LONG width, height, compr, dibsize;
|
||||||
WORD planes, bpp;
|
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)
|
pConvertedInfo = ConvertBitmapInfo(Data, ColorUse,
|
||||||
{
|
&ConvertedInfoSize, FALSE);
|
||||||
GdiSetLastError(ERROR_INVALID_PARAMETER);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NtGdiCreateDIBitmapInternal(hDC,
|
if (DIB_GetBitmapInfo(Header, &width, &height, &planes, &bpp, &compr, &dibsize) == -1)
|
||||||
width,
|
{
|
||||||
height,
|
GdiSetLastError(ERROR_INVALID_PARAMETER);
|
||||||
Init,
|
return NULL;
|
||||||
(LPBYTE)Bits,
|
}
|
||||||
(PBITMAPINFO)Data,
|
|
||||||
ColorUse,
|
if ( pConvertedInfo )
|
||||||
bpp,
|
{
|
||||||
dibsize,
|
if ( pConvertedInfo->bmiHeader.biSize >= sizeof(BITMAPINFOHEADER) )
|
||||||
0,
|
{
|
||||||
0);
|
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!!!!!
|
#if 0 // FIXME!!! This is a victim of the Win32k Initialization BUG!!!!!
|
||||||
|
@ -419,7 +585,25 @@ SetDIBits(HDC hdc,
|
||||||
CONST BITMAPINFO *lpbmi,
|
CONST BITMAPINFO *lpbmi,
|
||||||
UINT fuColorUse)
|
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
|
INT
|
||||||
STDCALL
|
STDCALL
|
||||||
SetDIBitsToDevice(
|
SetDIBitsToDevice(
|
||||||
HDC hDC,
|
HDC hdc,
|
||||||
int XDest,
|
int XDest,
|
||||||
int YDest,
|
int YDest,
|
||||||
DWORD Width,
|
DWORD Width,
|
||||||
|
@ -442,22 +626,111 @@ SetDIBitsToDevice(
|
||||||
CONST BITMAPINFO *lpbmi,
|
CONST BITMAPINFO *lpbmi,
|
||||||
UINT ColorUse)
|
UINT ColorUse)
|
||||||
{
|
{
|
||||||
return NtGdiSetDIBitsToDeviceInternal(hDC,
|
PDC_ATTR pDc_Attr;
|
||||||
XDest,
|
PBITMAPINFO pConvertedInfo;
|
||||||
YDest,
|
UINT ConvertedInfoSize;
|
||||||
Width,
|
INT LinesCopied = 0;
|
||||||
Height,
|
UINT cjBmpScanSize = 0;
|
||||||
XSrc,
|
PVOID pvSafeBits = (PVOID)Bits;
|
||||||
YSrc,
|
|
||||||
StartScan,
|
if ( !ScanLines || !lpbmi || !Bits )
|
||||||
ScanLines,
|
return 0;
|
||||||
(LPBYTE)Bits,
|
|
||||||
(LPBITMAPINFO)lpbmi,
|
if ( ColorUse && ColorUse != DIB_PAL_COLORS && ColorUse != DIB_PAL_COLORS+1 )
|
||||||
ColorUse,
|
return 0;
|
||||||
lpbmi->bmiHeader.biSizeImage,
|
|
||||||
lpbmi->bmiHeader.biSize,
|
pConvertedInfo = ConvertBitmapInfo(lpbmi, ColorUse,
|
||||||
TRUE,
|
&ConvertedInfoSize, FALSE);
|
||||||
NULL);
|
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)
|
DWORD dwRop)
|
||||||
|
|
||||||
{
|
{
|
||||||
DPRINT("StretchDIBits %x : %x\n", lpBits, lpBitsInfo);
|
PDC_ATTR pDc_Attr;
|
||||||
/* FIXME share memory */
|
PBITMAPINFO pConvertedInfo = NULL;
|
||||||
return NtGdiStretchDIBitsInternal(hdc, XDest, YDest, nDestWidth, nDestHeight, XSrc, YSrc,
|
UINT ConvertedInfoSize = 0;
|
||||||
nSrcWidth, nSrcHeight, (LPBYTE)lpBits, (LPBITMAPINFO)lpBitsInfo, (DWORD)iUsage, dwRop, 0, 0, NULL);
|
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 (FollowedByData)
|
||||||
{
|
{
|
||||||
if (BitmapInfo->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
DataSize = DIB_BitmapBitsSize((PBITMAPINFO)BitmapInfo );
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -270,6 +270,7 @@ BOOL FASTCALL IntGdiCleanDC(HDC hDC);
|
||||||
VOID FASTCALL IntvGetDeviceCaps(PGDIDEVICE, PDEVCAPS);
|
VOID FASTCALL IntvGetDeviceCaps(PGDIDEVICE, PDEVCAPS);
|
||||||
HPEN FASTCALL IntGdiSelectPen(PDC,HPEN);
|
HPEN FASTCALL IntGdiSelectPen(PDC,HPEN);
|
||||||
HBRUSH FASTCALL IntGdiSelectBrush(PDC,HBRUSH);
|
HBRUSH FASTCALL IntGdiSelectBrush(PDC,HBRUSH);
|
||||||
|
INT FASTCALL IntGdiGetDeviceCaps(PDC,INT);
|
||||||
|
|
||||||
extern PGDIDEVICE pPrimarySurface;
|
extern PGDIDEVICE pPrimarySurface;
|
||||||
|
|
||||||
|
|
|
@ -317,7 +317,7 @@ NtGdiSetDIBits(
|
||||||
DC_UnlockDc(Dc);
|
DC_UnlockDc(Dc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
// Need SEH to check Bits and bmi. BTW bmi was converted in gdi.
|
||||||
Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
|
Ret = IntSetDIBits(Dc, hBitmap, StartScan, ScanLines, Bits, bmi, ColorUse);
|
||||||
|
|
||||||
DC_UnlockDc(Dc);
|
DC_UnlockDc(Dc);
|
||||||
|
@ -399,7 +399,7 @@ NtGdiSetDIBitsToDeviceInternal(
|
||||||
ptSource.y = YSrc;
|
ptSource.y = YSrc;
|
||||||
|
|
||||||
/* Enter SEH, as the bits are user mode */
|
/* Enter SEH, as the bits are user mode */
|
||||||
_SEH_TRY
|
_SEH_TRY // Look at NtGdiStretchDIBitsInternal
|
||||||
{
|
{
|
||||||
SourceSize.cx = bmi->bmiHeader.biWidth;
|
SourceSize.cx = bmi->bmiHeader.biWidth;
|
||||||
SourceSize.cy = ScanLines;
|
SourceSize.cy = ScanLines;
|
||||||
|
@ -541,8 +541,8 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
||||||
/* fill out the BITMAPINFO struct */
|
/* fill out the BITMAPINFO struct */
|
||||||
if (Bits == NULL)
|
if (Bits == NULL)
|
||||||
{
|
{
|
||||||
_SEH_TRY
|
_SEH_TRY // Look at NtGdiStretchDIBitsInternal
|
||||||
{
|
{ // Why check for anything, we converted in gdi!
|
||||||
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||||
{
|
{
|
||||||
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
|
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
|
||||||
|
@ -806,6 +806,7 @@ NtGdiStretchDIBitsInternal(
|
||||||
HDC hdcMem;
|
HDC hdcMem;
|
||||||
HPALETTE hPal = NULL;
|
HPALETTE hPal = NULL;
|
||||||
PDC pDC;
|
PDC pDC;
|
||||||
|
BOOL Hit = FALSE;
|
||||||
|
|
||||||
if (!Bits || !BitsInfo)
|
if (!Bits || !BitsInfo)
|
||||||
{
|
{
|
||||||
|
@ -813,6 +814,23 @@ NtGdiStretchDIBitsInternal(
|
||||||
return 0;
|
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);
|
hdcMem = NtGdiCreateCompatibleDC(hDC);
|
||||||
if (hdcMem == NULL)
|
if (hdcMem == NULL)
|
||||||
{
|
{
|
||||||
|
@ -993,6 +1011,7 @@ NtGdiCreateDIBitmapInternal(IN HDC hDc,
|
||||||
{
|
{
|
||||||
PDC Dc;
|
PDC Dc;
|
||||||
HBITMAP Bmp;
|
HBITMAP Bmp;
|
||||||
|
UINT bpp;
|
||||||
|
|
||||||
if (!hDc)
|
if (!hDc)
|
||||||
{ // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
|
{ // Should use System Bitmap DC hSystemBM, with CreateCompatibleDC for this.
|
||||||
|
@ -1010,9 +1029,8 @@ NtGdiCreateDIBitmapInternal(IN HDC hDc,
|
||||||
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
bpp = IntGdiGetDeviceCaps(Dc, BITSPIXEL);
|
||||||
cjMaxInitInfo = 1;
|
Bmp = IntCreateDIBitmap(Dc, cx, cy, bpp, fInit, pjInit, pbmi, iUsage);
|
||||||
Bmp = IntCreateDIBitmap(Dc, cx, cy, cjMaxInitInfo, fInit, pjInit, pbmi, iUsage);
|
|
||||||
|
|
||||||
DC_UnlockDc(Dc);
|
DC_UnlockDc(Dc);
|
||||||
NtGdiDeleteObjectApp(hDc);
|
NtGdiDeleteObjectApp(hDc);
|
||||||
|
@ -1025,8 +1043,16 @@ NtGdiCreateDIBitmapInternal(IN HDC hDc,
|
||||||
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
||||||
return NULL;
|
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);
|
DC_UnlockDc(Dc);
|
||||||
}
|
}
|
||||||
return Bmp;
|
return Bmp;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue