mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 21:53:06 +00:00
[WIN32K]
- Rewrite NtGdiStretchDIBitsInternal : clearer, faster, stronger (+1 wine test) svn path=/branches/reactos-yarotows/; revision=48465
This commit is contained in:
parent
96444b43c2
commit
3f5d90a47a
1 changed files with 103 additions and 94 deletions
|
@ -290,7 +290,7 @@ IntSetDIBits(
|
|||
|
||||
if(!(psurfSrc && psurfDst))
|
||||
{
|
||||
DPRINT1("Error, could not lock surfaces.\n");
|
||||
DPRINT1("Error, could not lock surfaces\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
@ -1021,42 +1021,32 @@ NtGdiStretchDIBitsInternal(
|
|||
UINT cjMaxBits,
|
||||
HANDLE hcmXform)
|
||||
{
|
||||
HBITMAP hBitmap, hOldBitmap = NULL;
|
||||
HDC hdcMem = NULL;
|
||||
PDC pdc;
|
||||
INT ret = 0;
|
||||
LONG height;
|
||||
LONG width;
|
||||
WORD planes, bpp;
|
||||
DWORD compr, size;
|
||||
HBITMAP hBitmap;
|
||||
BOOL fastpath = FALSE;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PVOID pvDIBits;
|
||||
INT Ret = 0;
|
||||
|
||||
|
||||
if (!Bits || !BitsInfo)
|
||||
{
|
||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create a DIB Section, data will be probed there */
|
||||
hBitmap = NtGdiCreateDIBSection(hDC,
|
||||
NULL,
|
||||
0,
|
||||
BitsInfo,
|
||||
Usage,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&pvDIBits);
|
||||
if (!(pdc = DC_LockDc(hDC))) return 0;
|
||||
|
||||
if(!hBitmap)
|
||||
{
|
||||
DPRINT1("Failed to create a DIB.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set bits */
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForRead(BitsInfo, cjMaxInfo, 1);
|
||||
ProbeForRead(Bits, cjMaxBits, 1);
|
||||
RtlCopyMemory(pvDIBits, Bits, DIB_GetDIBImageBytes(BitsInfo->bmiHeader.biWidth,
|
||||
BitsInfo->bmiHeader.biHeight,
|
||||
BitsInfo->bmiHeader.biBitCount));
|
||||
if (DIB_GetBitmapInfo( &BitsInfo->bmiHeader, &width, &height, &planes, &bpp, &compr, &size ) == -1)
|
||||
{
|
||||
DPRINT1("Invalid bitmap\n");
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
|
@ -1066,50 +1056,69 @@ NtGdiStretchDIBitsInternal(
|
|||
|
||||
if(!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Error : Could not read DIB bits\n");
|
||||
SetLastNtError(Status);
|
||||
DPRINT1("Error, failed to read the DIB bits\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
hdcMem = NtGdiCreateCompatibleDC(0);
|
||||
if(!hdcMem)
|
||||
if (width < 0)
|
||||
{
|
||||
DPRINT1("Failed to create a memory DC!");
|
||||
goto cleanup;
|
||||
DPRINT1("Bitmap has a negative width\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
|
||||
if(!hOldBitmap)
|
||||
hBitmap = NtGdiGetDCObject(hDC, OBJ_BITMAP);
|
||||
|
||||
if (XDest == 0 && YDest == 0 && XSrc == 0 && XSrc == 0 &&
|
||||
DestWidth == SrcWidth && DestHeight == SrcHeight &&
|
||||
compr == BI_RGB &&
|
||||
ROP == SRCCOPY)
|
||||
{
|
||||
DPRINT1("Could not select the DIB into the memory DC\n");
|
||||
goto cleanup;
|
||||
BITMAP bmp;
|
||||
if (IntGdiGetObject(hBitmap, sizeof(bmp), &bmp) == sizeof(bmp))
|
||||
{
|
||||
if (bmp.bmBitsPixel == bpp &&
|
||||
bmp.bmWidth == SrcWidth &&
|
||||
bmp.bmHeight == SrcHeight &&
|
||||
bmp.bmPlanes == planes)
|
||||
fastpath = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Do we want to stretch ? */
|
||||
if((SrcWidth == DestWidth) && (SrcHeight == DestHeight))
|
||||
if (fastpath)
|
||||
{
|
||||
Ret = NtGdiBitBlt(hDC, XDest, YDest, XDest + DestWidth, YDest + DestHeight,
|
||||
hdcMem, XSrc, YSrc, ROP, 0, 0);
|
||||
/* fast path */
|
||||
DPRINT1("using fast path\n");
|
||||
ret = IntSetDIBits( pdc, hBitmap, 0, height, Bits, BitsInfo, Usage);
|
||||
}
|
||||
else
|
||||
{
|
||||
Ret = NtGdiStretchBlt(hDC, XDest, YDest, XDest + DestWidth, YDest + DestHeight,
|
||||
hdcMem, XSrc, YSrc, XSrc + SrcWidth, YSrc + SrcHeight,
|
||||
ROP, 0);
|
||||
/* slow path - need to use StretchBlt */
|
||||
HBITMAP hOldBitmap;
|
||||
HPALETTE hpal = NULL;
|
||||
HDC hdcMem;
|
||||
PVOID pvBits;
|
||||
|
||||
hdcMem = NtGdiCreateCompatibleDC( hDC );
|
||||
hBitmap = DIB_CreateDIBSection(pdc, BitsInfo, Usage, &pvBits, NULL, 0, 0);
|
||||
RtlCopyMemory(pvBits, Bits, cjMaxBits);
|
||||
hOldBitmap = NtGdiSelectBitmap( hdcMem, hBitmap );
|
||||
|
||||
/* Origin for DIBitmap may be bottom left (positive biHeight) or top
|
||||
left (negative biHeight) */
|
||||
ret = NtGdiStretchBlt( hDC, XDest, YDest, DestWidth, DestHeight,
|
||||
hdcMem, XSrc, abs(height) - SrcHeight - YSrc,
|
||||
SrcWidth, SrcHeight, ROP, 0 );
|
||||
if(hpal)
|
||||
GdiSelectPalette(hdcMem, hpal, FALSE);
|
||||
if(ret)
|
||||
ret = SrcHeight;
|
||||
NtGdiSelectBitmap( hdcMem, hOldBitmap );
|
||||
NtGdiDeleteObjectApp( hdcMem );
|
||||
GreDeleteObject( hBitmap );
|
||||
}
|
||||
|
||||
if(Ret)
|
||||
Ret = SrcHeight ;
|
||||
|
||||
cleanup:
|
||||
if(hdcMem)
|
||||
{
|
||||
if(hOldBitmap) NtGdiSelectBitmap(hdcMem, hOldBitmap);
|
||||
NtGdiDeleteObjectApp(hdcMem);
|
||||
}
|
||||
GreDeleteObject(hBitmap);
|
||||
|
||||
return Ret;
|
||||
DC_UnlockDc(pdc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1575,7 +1584,7 @@ DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
|
|||
*height = core->bcHeight;
|
||||
*planes = core->bcPlanes;
|
||||
*bpp = core->bcBitCount;
|
||||
*compr = 0;
|
||||
*compr = BI_RGB;
|
||||
*size = 0;
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue