mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 12:13:01 +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))
|
if(!(psurfSrc && psurfDst))
|
||||||
{
|
{
|
||||||
DPRINT1("Error, could not lock surfaces.\n");
|
DPRINT1("Error, could not lock surfaces\n");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -663,15 +663,15 @@ NtGdiGetDIBitsInternal(
|
||||||
if(pbmci)
|
if(pbmci)
|
||||||
{
|
{
|
||||||
pbmci->bmciHeader.bcWidth = psurf->SurfObj.sizlBitmap.cx;
|
pbmci->bmciHeader.bcWidth = psurf->SurfObj.sizlBitmap.cx;
|
||||||
pbmci->bmciHeader.bcHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
|
pbmci->bmciHeader.bcHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
|
||||||
-psurf->SurfObj.sizlBitmap.cy :
|
-psurf->SurfObj.sizlBitmap.cy :
|
||||||
psurf->SurfObj.sizlBitmap.cy;
|
psurf->SurfObj.sizlBitmap.cy;
|
||||||
pbmci->bmciHeader.bcPlanes = 1;
|
pbmci->bmciHeader.bcPlanes = 1;
|
||||||
pbmci->bmciHeader.bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
|
pbmci->bmciHeader.bcBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
|
||||||
}
|
}
|
||||||
Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
|
Info->bmiHeader.biWidth = psurf->SurfObj.sizlBitmap.cx;
|
||||||
Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
|
Info->bmiHeader.biHeight = (psurf->SurfObj.fjBitmap & BMF_TOPDOWN) ?
|
||||||
-psurf->SurfObj.sizlBitmap.cy :
|
-psurf->SurfObj.sizlBitmap.cy :
|
||||||
psurf->SurfObj.sizlBitmap.cy;;
|
psurf->SurfObj.sizlBitmap.cy;;
|
||||||
Info->bmiHeader.biPlanes = 1;
|
Info->bmiHeader.biPlanes = 1;
|
||||||
Info->bmiHeader.biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
|
Info->bmiHeader.biBitCount = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
|
||||||
|
@ -711,15 +711,15 @@ NtGdiGetDIBitsInternal(
|
||||||
case 8:
|
case 8:
|
||||||
Info->bmiHeader.biClrUsed = 0;
|
Info->bmiHeader.biClrUsed = 0;
|
||||||
|
|
||||||
/* If the bitmap if a DIB section and has the same format than what
|
/* If the bitmap if a DIB section and has the same format than what
|
||||||
* we're asked, go ahead! */
|
* we're asked, go ahead! */
|
||||||
if((psurf->hSecure) &&
|
if((psurf->hSecure) &&
|
||||||
(BitsPerFormat(psurf->SurfObj.iBitmapFormat) == bpp))
|
(BitsPerFormat(psurf->SurfObj.iBitmapFormat) == bpp))
|
||||||
{
|
{
|
||||||
if(Usage == DIB_RGB_COLORS)
|
if(Usage == DIB_RGB_COLORS)
|
||||||
{
|
{
|
||||||
unsigned int colors = min(psurf->ppal->NumColors, 1 << bpp);
|
unsigned int colors = min(psurf->ppal->NumColors, 1 << bpp);
|
||||||
|
|
||||||
if(pbmci)
|
if(pbmci)
|
||||||
{
|
{
|
||||||
for(i=0; i < colors; i++)
|
for(i=0; i < colors; i++)
|
||||||
|
@ -773,7 +773,7 @@ NtGdiGetDIBitsInternal(
|
||||||
rgbTriples[i].rgbtGreen = pDcPal->IndexedColors[i].peGreen;
|
rgbTriples[i].rgbtGreen = pDcPal->IndexedColors[i].peGreen;
|
||||||
rgbTriples[i].rgbtBlue = pDcPal->IndexedColors[i].peBlue;
|
rgbTriples[i].rgbtBlue = pDcPal->IndexedColors[i].peBlue;
|
||||||
}
|
}
|
||||||
|
|
||||||
rgbQuads[i].rgbRed = pDcPal->IndexedColors[i].peRed;
|
rgbQuads[i].rgbRed = pDcPal->IndexedColors[i].peRed;
|
||||||
rgbQuads[i].rgbGreen = pDcPal->IndexedColors[i].peGreen;
|
rgbQuads[i].rgbGreen = pDcPal->IndexedColors[i].peGreen;
|
||||||
rgbQuads[i].rgbBlue = pDcPal->IndexedColors[i].peBlue;
|
rgbQuads[i].rgbBlue = pDcPal->IndexedColors[i].peBlue;
|
||||||
|
@ -822,7 +822,7 @@ NtGdiGetDIBitsInternal(
|
||||||
{
|
{
|
||||||
for(g = 0; g <= 5; g++)
|
for(g = 0; g <= 5; g++)
|
||||||
{
|
{
|
||||||
for(b = 0; b <= 5; b++)
|
for(b = 0; b <= 5; b++)
|
||||||
{
|
{
|
||||||
colorTriple->rgbtRed = (r * 0xff) / 5;
|
colorTriple->rgbtRed = (r * 0xff) / 5;
|
||||||
colorTriple->rgbtGreen = (g * 0xff) / 5;
|
colorTriple->rgbtGreen = (g * 0xff) / 5;
|
||||||
|
@ -935,7 +935,7 @@ NtGdiGetDIBitsInternal(
|
||||||
/* Restore them */
|
/* Restore them */
|
||||||
Info->bmiHeader.biWidth = width;
|
Info->bmiHeader.biWidth = width;
|
||||||
Info->bmiHeader.biHeight = height;
|
Info->bmiHeader.biHeight = height;
|
||||||
|
|
||||||
if(!hBmpDest)
|
if(!hBmpDest)
|
||||||
{
|
{
|
||||||
DPRINT1("Unable to create a DIB Section!\n");
|
DPRINT1("Unable to create a DIB Section!\n");
|
||||||
|
@ -972,7 +972,7 @@ NtGdiGetDIBitsInternal(
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, height, bpp));
|
RtlCopyMemory(Bits, pDIBits, DIB_GetDIBImageBytes (width, height, bpp));
|
||||||
}
|
}
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
{
|
{
|
||||||
Status = _SEH2_GetExceptionCode();
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
@ -1021,95 +1021,104 @@ NtGdiStretchDIBitsInternal(
|
||||||
UINT cjMaxBits,
|
UINT cjMaxBits,
|
||||||
HANDLE hcmXform)
|
HANDLE hcmXform)
|
||||||
{
|
{
|
||||||
HBITMAP hBitmap, hOldBitmap = NULL;
|
PDC pdc;
|
||||||
HDC hdcMem = NULL;
|
INT ret = 0;
|
||||||
|
LONG height;
|
||||||
|
LONG width;
|
||||||
|
WORD planes, bpp;
|
||||||
|
DWORD compr, size;
|
||||||
|
HBITMAP hBitmap;
|
||||||
|
BOOL fastpath = FALSE;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PVOID pvDIBits;
|
|
||||||
INT Ret = 0;
|
|
||||||
|
|
||||||
if (!Bits || !BitsInfo)
|
if (!Bits || !BitsInfo)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!(pdc = DC_LockDc(hDC))) return 0;
|
||||||
|
|
||||||
|
|
||||||
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
SetLastWin32Error(ERROR_INVALID_PARAMETER);
|
ProbeForRead(BitsInfo, cjMaxInfo, 1);
|
||||||
|
ProbeForRead(Bits, cjMaxBits, 1);
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
Status = _SEH2_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH2_END
|
||||||
|
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Error, failed to read the DIB bits\n");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (width < 0)
|
||||||
|
{
|
||||||
|
DPRINT1("Bitmap has a negative width\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a DIB Section, data will be probed there */
|
hBitmap = NtGdiGetDCObject(hDC, OBJ_BITMAP);
|
||||||
hBitmap = NtGdiCreateDIBSection(hDC,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
BitsInfo,
|
|
||||||
Usage,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
&pvDIBits);
|
|
||||||
|
|
||||||
if(!hBitmap)
|
if (XDest == 0 && YDest == 0 && XSrc == 0 && XSrc == 0 &&
|
||||||
{
|
DestWidth == SrcWidth && DestHeight == SrcHeight &&
|
||||||
DPRINT1("Failed to create a DIB.\n");
|
compr == BI_RGB &&
|
||||||
return 0;
|
ROP == SRCCOPY)
|
||||||
}
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Set bits */
|
if (fastpath)
|
||||||
_SEH2_TRY
|
{
|
||||||
{
|
/* fast path */
|
||||||
ProbeForRead(Bits, cjMaxBits, 1);
|
DPRINT1("using fast path\n");
|
||||||
RtlCopyMemory(pvDIBits, Bits, DIB_GetDIBImageBytes(BitsInfo->bmiHeader.biWidth,
|
ret = IntSetDIBits( pdc, hBitmap, 0, height, Bits, BitsInfo, Usage);
|
||||||
BitsInfo->bmiHeader.biHeight,
|
}
|
||||||
BitsInfo->bmiHeader.biBitCount));
|
else
|
||||||
}
|
{
|
||||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
/* slow path - need to use StretchBlt */
|
||||||
{
|
HBITMAP hOldBitmap;
|
||||||
Status = _SEH2_GetExceptionCode();
|
HPALETTE hpal = NULL;
|
||||||
}
|
HDC hdcMem;
|
||||||
_SEH2_END
|
PVOID pvBits;
|
||||||
|
|
||||||
if(!NT_SUCCESS(Status))
|
hdcMem = NtGdiCreateCompatibleDC( hDC );
|
||||||
{
|
hBitmap = DIB_CreateDIBSection(pdc, BitsInfo, Usage, &pvBits, NULL, 0, 0);
|
||||||
DPRINT1("Error : Could not read DIB bits\n");
|
RtlCopyMemory(pvBits, Bits, cjMaxBits);
|
||||||
SetLastNtError(Status);
|
hOldBitmap = NtGdiSelectBitmap( hdcMem, hBitmap );
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
hdcMem = NtGdiCreateCompatibleDC(0);
|
|
||||||
if(!hdcMem)
|
|
||||||
{
|
|
||||||
DPRINT1("Failed to create a memory DC!");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
hOldBitmap = NtGdiSelectBitmap(hdcMem, hBitmap);
|
|
||||||
if(!hOldBitmap)
|
|
||||||
{
|
|
||||||
DPRINT1("Could not select the DIB into the memory DC\n");
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Do we want to stretch ? */
|
|
||||||
if((SrcWidth == DestWidth) && (SrcHeight == DestHeight))
|
|
||||||
{
|
|
||||||
Ret = NtGdiBitBlt(hDC, XDest, YDest, XDest + DestWidth, YDest + DestHeight,
|
|
||||||
hdcMem, XSrc, YSrc, ROP, 0, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Ret = NtGdiStretchBlt(hDC, XDest, YDest, XDest + DestWidth, YDest + DestHeight,
|
|
||||||
hdcMem, XSrc, YSrc, XSrc + SrcWidth, YSrc + SrcHeight,
|
|
||||||
ROP, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Ret)
|
|
||||||
Ret = SrcHeight ;
|
|
||||||
|
|
||||||
|
/* 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 );
|
||||||
|
}
|
||||||
cleanup:
|
cleanup:
|
||||||
if(hdcMem)
|
DC_UnlockDc(pdc);
|
||||||
{
|
return ret;
|
||||||
if(hOldBitmap) NtGdiSelectBitmap(hdcMem, hOldBitmap);
|
|
||||||
NtGdiDeleteObjectApp(hdcMem);
|
|
||||||
}
|
|
||||||
GreDeleteObject(hBitmap);
|
|
||||||
|
|
||||||
return Ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1462,7 +1471,7 @@ DIB_CreateDIBSection(
|
||||||
hpal = (HPALETTE) 0xFFFFFFFF;
|
hpal = (HPALETTE) 0xFFFFFFFF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hpal = BuildDIBPalette(bmi);
|
hpal = BuildDIBPalette(bmi);
|
||||||
}
|
}
|
||||||
|
@ -1563,7 +1572,7 @@ cleanup:
|
||||||
* Get the info from a bitmap header.
|
* Get the info from a bitmap header.
|
||||||
* Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error.
|
* Return 0 for COREHEADER, 1 for INFOHEADER, -1 for error.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
FASTCALL
|
FASTCALL
|
||||||
DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
|
DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
|
||||||
LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size )
|
LONG *height, WORD *planes, WORD *bpp, DWORD *compr, DWORD *size )
|
||||||
|
@ -1575,7 +1584,7 @@ DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
|
||||||
*height = core->bcHeight;
|
*height = core->bcHeight;
|
||||||
*planes = core->bcPlanes;
|
*planes = core->bcPlanes;
|
||||||
*bpp = core->bcBitCount;
|
*bpp = core->bcBitCount;
|
||||||
*compr = 0;
|
*compr = BI_RGB;
|
||||||
*size = 0;
|
*size = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1692,10 +1701,10 @@ DIB_MapPaletteColors(PPALETTE ppal, CONST BITMAPINFO* lpbmi)
|
||||||
ppalEntries[i].peBlue = 0;
|
ppalEntries[i].peBlue = 0;
|
||||||
ppalEntries[i].peFlags = 0;
|
ppalEntries[i].peFlags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
lpIndex++;
|
lpIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
hpal = PALETTE_AllocPalette(PAL_INDEXED, nNumColors, (ULONG*)ppalEntries, 0, 0, 0);
|
hpal = PALETTE_AllocPalette(PAL_INDEXED, nNumColors, (ULONG*)ppalEntries, 0, 0, 0);
|
||||||
|
|
||||||
ExFreePoolWithTag(ppalEntries, TAG_COLORMAP);
|
ExFreePoolWithTag(ppalEntries, TAG_COLORMAP);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue