Improve NtGdiStretchDIBitsInternal, use _SEH2_YIELT instead of saving an NTSTATUS and handle the fast path in place instead of setting a BOOL variable. Fixes warnings about uninitialized variables.

svn path=/trunk/; revision=50342
This commit is contained in:
Timo Kreuzer 2011-01-09 18:11:44 +00:00
parent e6182247f6
commit 3ecc17156e

View file

@ -1028,50 +1028,46 @@ NtGdiStretchDIBitsInternal(
WORD planes, bpp; WORD planes, bpp;
DWORD compr, size; DWORD compr, size;
HBITMAP hBitmap; HBITMAP hBitmap;
BOOL fastpath = FALSE; HBITMAP hOldBitmap;
NTSTATUS Status = STATUS_SUCCESS; HDC hdcMem;
PBYTE safeBits ; PVOID pvBits;
PBYTE safeBits;
if (!Bits || !BitsInfo) if (!Bits || !BitsInfo)
return 0; return 0;
safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB); safeBits = ExAllocatePoolWithTag(PagedPool, cjMaxBits, TAG_DIB);
if(!safeBits) if(!safeBits)
{ {
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY); EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0; return 0;
} }
if (!(pdc = DC_LockDc(hDC))) if (!(pdc = DC_LockDc(hDC)))
{ {
ExFreePoolWithTag(safeBits, TAG_DIB); ExFreePoolWithTag(safeBits, TAG_DIB);
EngSetLastError(ERROR_INVALID_HANDLE); EngSetLastError(ERROR_INVALID_HANDLE);
return 0; return 0;
} }
_SEH2_TRY _SEH2_TRY
{ {
ProbeForRead(BitsInfo, cjMaxInfo, 1); ProbeForRead(BitsInfo, cjMaxInfo, 1);
ProbeForRead(Bits, cjMaxBits, 1); ProbeForRead(Bits, cjMaxBits, 1);
if (DIB_GetBitmapInfo( &BitsInfo->bmiHeader, &width, &height, &planes, &bpp, &compr, &size ) == -1) if (DIB_GetBitmapInfo(&BitsInfo->bmiHeader, &width, &height, &planes, &bpp, &compr, &size) == -1)
{ {
DPRINT1("Invalid bitmap\n"); DPRINT1("Invalid bitmap\n");
Status = STATUS_INVALID_PARAMETER; _SEH2_YIELD(goto cleanup;)
} }
RtlCopyMemory(safeBits, Bits, cjMaxBits); RtlCopyMemory(safeBits, Bits, cjMaxBits);
} }
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{ {
Status = _SEH2_GetExceptionCode(); DPRINT1("Error, failed to read the DIB bits\n");
_SEH2_YIELD(goto cleanup;)
} }
_SEH2_END _SEH2_END
if(!NT_SUCCESS(Status))
{
DPRINT1("Error, failed to read the DIB bits\n");
goto cleanup;
}
if (width < 0) if (width < 0)
{ {
DPRINT1("Bitmap has a negative width\n"); DPRINT1("Bitmap has a negative width\n");
@ -1086,54 +1082,47 @@ NtGdiStretchDIBitsInternal(
ROP == SRCCOPY) ROP == SRCCOPY)
{ {
BITMAP bmp; BITMAP bmp;
if (IntGdiGetObject(hBitmap, sizeof(bmp), &bmp) == sizeof(bmp)) ret = IntGdiGetObject(hBitmap, sizeof(bmp), &bmp) == sizeof(bmp);
if (ret &&
bmp.bmBitsPixel == bpp &&
bmp.bmWidth == SrcWidth &&
bmp.bmHeight == SrcHeight &&
bmp.bmPlanes == planes)
{ {
if (bmp.bmBitsPixel == bpp && /* fast path */
bmp.bmWidth == SrcWidth && ret = IntSetDIBits(pdc, hBitmap, 0, height, safeBits, BitsInfo, Usage);
bmp.bmHeight == SrcHeight && goto cleanup;
bmp.bmPlanes == planes)
fastpath = TRUE;
} }
} }
if (fastpath) /* slow path - need to use StretchBlt */
{
/* fast path */
DPRINT1("using fast path\n");
ret = IntSetDIBits( pdc, hBitmap, 0, height, safeBits, BitsInfo, Usage);
}
else
{
/* slow path - need to use StretchBlt */
HBITMAP hOldBitmap;
HDC hdcMem;
PVOID pvBits;
hdcMem = NtGdiCreateCompatibleDC( hDC ); hdcMem = NtGdiCreateCompatibleDC(hDC);
hBitmap = DIB_CreateDIBSection(pdc, BitsInfo, Usage, &pvBits, NULL, 0, 0); hBitmap = DIB_CreateDIBSection(pdc, BitsInfo, Usage, &pvBits, NULL, 0, 0);
if(!hBitmap) if(!hBitmap)
{ {
DPRINT1("Error, failed to create a DIB section\n"); DPRINT1("Error, failed to create a DIB section\n");
NtGdiDeleteObjectApp(hdcMem); NtGdiDeleteObjectApp(hdcMem);
goto cleanup; goto cleanup;
}
RtlCopyMemory(pvBits, safeBits, 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(ret)
ret = SrcHeight;
NtGdiSelectBitmap( hdcMem, hOldBitmap );
NtGdiDeleteObjectApp( hdcMem );
GreDeleteObject( hBitmap );
} }
RtlCopyMemory(pvBits, safeBits, 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(ret)
ret = SrcHeight;
NtGdiSelectBitmap(hdcMem, hOldBitmap);
NtGdiDeleteObjectApp(hdcMem);
GreDeleteObject(hBitmap);
cleanup: cleanup:
ExFreePoolWithTag(safeBits, TAG_DIB); ExFreePoolWithTag(safeBits, TAG_DIB);
DC_UnlockDc(pdc); DC_UnlockDc(pdc);
return ret; return ret;
} }