mirror of
https://github.com/reactos/reactos.git
synced 2025-04-21 04:37:15 +00:00
- partial rewrite of NtGdiGetDIBitsInternal
- wrap all usermode read/writes in seh - make it more compatible with XP. We now pass all current GetDIBits tests and win32k tests svn path=/trunk/; revision=29326
This commit is contained in:
parent
82a49a076e
commit
ecf21c9be9
2 changed files with 185 additions and 122 deletions
|
@ -435,6 +435,7 @@ NtGdiSetDIBitsToDeviceInternal(
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Converts a device-dependent bitmap to a DIB */
|
/* Converts a device-dependent bitmap to a DIB */
|
||||||
INT STDCALL
|
INT STDCALL
|
||||||
NtGdiGetDIBitsInternal(HDC hDC,
|
NtGdiGetDIBitsInternal(HDC hDC,
|
||||||
|
@ -447,67 +448,63 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
||||||
UINT MaxBits,
|
UINT MaxBits,
|
||||||
UINT MaxInfo)
|
UINT MaxInfo)
|
||||||
{
|
{
|
||||||
BITMAPOBJ *BitmapObj;
|
|
||||||
SURFOBJ *DestSurfObj;
|
|
||||||
XLATEOBJ *XlateObj;
|
|
||||||
HBITMAP DestBitmap;
|
|
||||||
SIZEL DestSize;
|
|
||||||
HPALETTE hSourcePalette;
|
|
||||||
HPALETTE hDestPalette;
|
|
||||||
PPALGDI SourcePalette;
|
|
||||||
PPALGDI DestPalette;
|
|
||||||
ULONG SourcePaletteType;
|
|
||||||
ULONG DestPaletteType;
|
|
||||||
PDC Dc;
|
PDC Dc;
|
||||||
POINTL SourcePoint;
|
BITMAPOBJ *BitmapObj = NULL;
|
||||||
RECTL DestRect;
|
HBITMAP hDestBitmap = NULL;
|
||||||
|
HPALETTE hSourcePalette = NULL;
|
||||||
|
HPALETTE hDestPalette = NULL;
|
||||||
|
PPALGDI SourcePalette = NULL;
|
||||||
|
PPALGDI DestPalette = NULL;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
ULONG Result = 0;
|
ULONG Result = 0;
|
||||||
ULONG Index;
|
BOOL bPaletteMatch = FALSE;
|
||||||
|
|
||||||
|
DPRINT("Entered NtGdiGetDIBitsInternal()\n");
|
||||||
|
|
||||||
/* Get handle for the palette in DC. */
|
/* Get handle for the palette in DC. */
|
||||||
Dc = DC_LockDc(hDC);
|
Dc = DC_LockDc(hDC);
|
||||||
if (Dc == NULL)
|
if (Dc == NULL) return 0;
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if (Dc->IsIC)
|
if (Dc->IsIC)
|
||||||
{
|
{
|
||||||
DC_UnlockDc(Dc);
|
DC_UnlockDc(Dc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
/* Source palette obtained from the windows hdc */
|
||||||
hSourcePalette = Dc->w.hPalette;
|
hSourcePalette = Dc->w.hPalette;
|
||||||
hDestPalette = Dc->w.hPalette; // unsure of this (Ged)
|
|
||||||
DC_UnlockDc(Dc);
|
DC_UnlockDc(Dc);
|
||||||
|
|
||||||
/* Get pointer to the source bitmap object. */
|
/* don't do anything if we fail this */
|
||||||
|
if (Usage != DIB_RGB_COLORS && Usage != DIB_PAL_COLORS)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Get a pointer to the source bitmap object */
|
||||||
BitmapObj = BITMAPOBJ_LockBitmap(hBitmap);
|
BitmapObj = BITMAPOBJ_LockBitmap(hBitmap);
|
||||||
if (BitmapObj == NULL)
|
if (BitmapObj == NULL)
|
||||||
{
|
|
||||||
SetLastWin32Error(ERROR_INVALID_HANDLE);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
|
/* fill out the BITMAPINFO struct */
|
||||||
if (Bits == NULL)
|
if (Bits == NULL)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||||
{
|
{
|
||||||
|
ProbeForWrite(Info, sizeof(BITMAPINFO), 1);
|
||||||
|
|
||||||
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
|
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
|
||||||
coreheader->bcWidth =BitmapObj->SurfObj.sizlBitmap.cx;
|
coreheader->bcWidth =BitmapObj->SurfObj.sizlBitmap.cx;
|
||||||
coreheader->bcPlanes = 1;
|
coreheader->bcPlanes = 1;
|
||||||
coreheader->bcBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
|
coreheader->bcBitCount = BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat);
|
||||||
|
|
||||||
coreheader->bcHeight = BitmapObj->SurfObj.sizlBitmap.cy;
|
coreheader->bcHeight = BitmapObj->SurfObj.sizlBitmap.cy;
|
||||||
|
|
||||||
if (BitmapObj->SurfObj.lDelta > 0)
|
if (BitmapObj->SurfObj.lDelta > 0)
|
||||||
coreheader->bcHeight = -coreheader->bcHeight;
|
coreheader->bcHeight = -coreheader->bcHeight;
|
||||||
|
|
||||||
Result = BitmapObj->SurfObj.sizlBitmap.cy;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
|
if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
|
||||||
{
|
{
|
||||||
|
ProbeForWrite(Info, sizeof(BITMAPINFO), 1);
|
||||||
|
|
||||||
Info->bmiHeader.biWidth = BitmapObj->SurfObj.sizlBitmap.cx;
|
Info->bmiHeader.biWidth = BitmapObj->SurfObj.sizlBitmap.cx;
|
||||||
Info->bmiHeader.biHeight = BitmapObj->SurfObj.sizlBitmap.cy;
|
Info->bmiHeader.biHeight = BitmapObj->SurfObj.sizlBitmap.cy;
|
||||||
/* Report negtive height for top-down bitmaps. */
|
/* Report negtive height for top-down bitmaps. */
|
||||||
|
@ -546,57 +543,39 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
||||||
Info->bmiHeader.biYPelsPerMeter = 0; /* FIXME */
|
Info->bmiHeader.biYPelsPerMeter = 0; /* FIXME */
|
||||||
Info->bmiHeader.biClrUsed = 0;
|
Info->bmiHeader.biClrUsed = 0;
|
||||||
Info->bmiHeader.biClrImportant = 1 << Info->bmiHeader.biBitCount; /* FIXME */
|
Info->bmiHeader.biClrImportant = 1 << Info->bmiHeader.biBitCount; /* FIXME */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
Result = BitmapObj->SurfObj.sizlBitmap.cy;
|
Result = BitmapObj->SurfObj.sizlBitmap.cy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (StartScan > BitmapObj->SurfObj.sizlBitmap.cy)
|
SIZEL DestSize;
|
||||||
|
ULONG SourcePaletteType = 0;
|
||||||
|
ULONG DestPaletteType;
|
||||||
|
POINTL SourcePoint;
|
||||||
|
ULONG Index;
|
||||||
|
|
||||||
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
Result = 0;
|
ProbeForRead(Info, sizeof(BITMAPINFO), 1);
|
||||||
|
|
||||||
|
if (Info->bmiHeader.biBitCount == BitsPerFormat(BitmapObj->SurfObj.iBitmapFormat))
|
||||||
|
{
|
||||||
|
hDestPalette = hSourcePalette;
|
||||||
|
bPaletteMatch = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
hDestPalette = BuildDIBPalette(Info, (PINT)&DestPaletteType); //hDestPalette = Dc->DevInfo->hpalDefault;
|
||||||
ScanLines = min(ScanLines, BitmapObj->SurfObj.sizlBitmap.cy - StartScan);
|
|
||||||
DestSize.cx = BitmapObj->SurfObj.sizlBitmap.cx;
|
|
||||||
DestSize.cy = ScanLines;
|
|
||||||
|
|
||||||
DestBitmap = NULL;
|
|
||||||
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
|
||||||
{
|
|
||||||
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
|
|
||||||
|
|
||||||
DestBitmap = EngCreateBitmap(DestSize,
|
|
||||||
DIB_GetDIBWidthBytes(DestSize.cx, coreheader->bcBitCount),
|
|
||||||
BitmapFormat(coreheader->bcBitCount, BI_RGB),
|
|
||||||
0 < coreheader->bcHeight ? 0 : BMF_TOPDOWN,
|
|
||||||
Bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
|
|
||||||
{
|
|
||||||
INT one, two, three;
|
|
||||||
|
|
||||||
one = DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount),
|
|
||||||
two = ((DestSize.cx * Info->bmiHeader.biBitCount + 31) & ~31) >> 3;
|
|
||||||
three = DestSize.cx * (Info->bmiHeader.biBitCount >> 3);
|
|
||||||
|
|
||||||
DestBitmap = EngCreateBitmap(DestSize,
|
|
||||||
/* DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount), */
|
|
||||||
DestSize.cx * (Info->bmiHeader.biBitCount >> 3), /* HACK */
|
|
||||||
BitmapFormat(Info->bmiHeader.biBitCount, Info->bmiHeader.biCompression),
|
|
||||||
0 < Info->bmiHeader.biHeight ? 0 : BMF_TOPDOWN,
|
|
||||||
Bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(DestBitmap == NULL)
|
|
||||||
{
|
|
||||||
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DestSurfObj = EngLockSurface((HSURF)DestBitmap);
|
|
||||||
|
|
||||||
SourcePalette = PALETTE_LockPalette(hSourcePalette);
|
SourcePalette = PALETTE_LockPalette(hSourcePalette);
|
||||||
/* FIXME - SourcePalette can be NULL!!! Don't assert here! */
|
/* FIXME - SourcePalette can be NULL!!! Don't assert here! */
|
||||||
|
@ -604,10 +583,18 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
||||||
SourcePaletteType = SourcePalette->Mode;
|
SourcePaletteType = SourcePalette->Mode;
|
||||||
PALETTE_UnlockPalette(SourcePalette);
|
PALETTE_UnlockPalette(SourcePalette);
|
||||||
|
|
||||||
|
if (bPaletteMatch)
|
||||||
|
{
|
||||||
DestPalette = PALETTE_LockPalette(hDestPalette);
|
DestPalette = PALETTE_LockPalette(hDestPalette);
|
||||||
/* FIXME - DestPalette can be NULL!!!! Don't assert here!!! */
|
/* FIXME - DestPalette can be NULL!!!! Don't assert here!!! */
|
||||||
//ASSERT(DestPalette);
|
DPRINT1("DestPalette : %p\n", DestPalette);
|
||||||
|
ASSERT(DestPalette);
|
||||||
DestPaletteType = DestPalette->Mode;
|
DestPaletteType = DestPalette->Mode;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DestPalette = SourcePalette;
|
||||||
|
}
|
||||||
|
|
||||||
/* Copy palette. */
|
/* Copy palette. */
|
||||||
/* FIXME: This is largely incomplete. */
|
/* FIXME: This is largely incomplete. */
|
||||||
|
@ -631,9 +618,65 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (bPaletteMatch)
|
||||||
PALETTE_UnlockPalette(DestPalette);
|
PALETTE_UnlockPalette(DestPalette);
|
||||||
|
|
||||||
XlateObj = IntEngCreateXlate(DestPaletteType, SourcePaletteType, hDestPalette, hSourcePalette);
|
/* Create the destination bitmap to for the copy operation */
|
||||||
|
if (StartScan > BitmapObj->SurfObj.sizlBitmap.cy)
|
||||||
|
{
|
||||||
|
_SEH_YIELD(goto cleanup);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ScanLines = min(ScanLines, BitmapObj->SurfObj.sizlBitmap.cy - StartScan);
|
||||||
|
DestSize.cx = BitmapObj->SurfObj.sizlBitmap.cx;
|
||||||
|
DestSize.cy = ScanLines;
|
||||||
|
|
||||||
|
hDestBitmap = NULL;
|
||||||
|
|
||||||
|
ProbeForWrite(Bits, sizeof(BitmapObj->SurfObj.cjBits), 1);
|
||||||
|
|
||||||
|
if (Info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
|
||||||
|
{
|
||||||
|
BITMAPCOREHEADER* coreheader = (BITMAPCOREHEADER*) Info;
|
||||||
|
|
||||||
|
hDestBitmap = EngCreateBitmap(DestSize,
|
||||||
|
DIB_GetDIBWidthBytes(DestSize.cx, coreheader->bcBitCount),
|
||||||
|
BitmapFormat(coreheader->bcBitCount, BI_RGB),
|
||||||
|
0 < coreheader->bcHeight ? 0 : BMF_TOPDOWN,
|
||||||
|
Bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER))
|
||||||
|
{
|
||||||
|
hDestBitmap = EngCreateBitmap(DestSize,
|
||||||
|
/* DIB_GetDIBWidthBytes(DestSize.cx, Info->bmiHeader.biBitCount), */
|
||||||
|
DestSize.cx * (Info->bmiHeader.biBitCount >> 3), /* HACK */
|
||||||
|
BitmapFormat(Info->bmiHeader.biBitCount, Info->bmiHeader.biCompression),
|
||||||
|
0 < Info->bmiHeader.biHeight ? 0 : BMF_TOPDOWN,
|
||||||
|
Bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hDestBitmap == NULL)
|
||||||
|
_SEH_YIELD(goto cleanup);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
Status = _SEH_GetExceptionCode();
|
||||||
|
}
|
||||||
|
_SEH_END
|
||||||
|
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
XLATEOBJ *XlateObj;
|
||||||
|
SURFOBJ *DestSurfObj;
|
||||||
|
RECTL DestRect;
|
||||||
|
|
||||||
|
XlateObj = IntEngCreateXlate(DestPaletteType,
|
||||||
|
SourcePaletteType,
|
||||||
|
hDestPalette,
|
||||||
|
hSourcePalette);
|
||||||
|
|
||||||
SourcePoint.x = 0;
|
SourcePoint.x = 0;
|
||||||
SourcePoint.y = BitmapObj->SurfObj.sizlBitmap.cy - (StartScan + ScanLines);
|
SourcePoint.y = BitmapObj->SurfObj.sizlBitmap.cy - (StartScan + ScanLines);
|
||||||
|
@ -644,6 +687,8 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
||||||
DestRect.right = DestSize.cx;
|
DestRect.right = DestSize.cx;
|
||||||
DestRect.bottom = DestSize.cy;
|
DestRect.bottom = DestSize.cy;
|
||||||
|
|
||||||
|
DestSurfObj = EngLockSurface((HSURF)hDestBitmap);
|
||||||
|
|
||||||
if (EngCopyBits(DestSurfObj,
|
if (EngCopyBits(DestSurfObj,
|
||||||
&BitmapObj->SurfObj,
|
&BitmapObj->SurfObj,
|
||||||
NULL,
|
NULL,
|
||||||
|
@ -659,8 +704,17 @@ NtGdiGetDIBitsInternal(HDC hDC,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
if (hDestBitmap != NULL)
|
||||||
|
EngDeleteSurface((HSURF)hDestBitmap);
|
||||||
|
|
||||||
|
if (hDestPalette != NULL && bPaletteMatch == FALSE)
|
||||||
|
PALETTE_FreePalette(hDestPalette);
|
||||||
|
|
||||||
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
BITMAPOBJ_UnlockBitmap(BitmapObj);
|
||||||
|
|
||||||
|
DPRINT("leaving NtGdiGetDIBitsInternal\n");
|
||||||
|
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1318,14 +1372,18 @@ BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType)
|
||||||
// Determine Bits Per Pixel
|
// Determine Bits Per Pixel
|
||||||
bits = bmi->bmiHeader.biBitCount;
|
bits = bmi->bmiHeader.biBitCount;
|
||||||
|
|
||||||
|
//DPRINT1("%d bits\n", bits);
|
||||||
|
|
||||||
// Determine paletteType from Bits Per Pixel
|
// Determine paletteType from Bits Per Pixel
|
||||||
if (bits <= 8)
|
if (bits <= 8)
|
||||||
{
|
{
|
||||||
|
//DPRINT1("8\n");
|
||||||
*paletteType = PAL_INDEXED;
|
*paletteType = PAL_INDEXED;
|
||||||
RedMask = GreenMask = BlueMask = 0;
|
RedMask = GreenMask = BlueMask = 0;
|
||||||
}
|
}
|
||||||
else if(bits < 24)
|
else if(bits < 24)
|
||||||
{
|
{
|
||||||
|
//DPRINT1("24\n");
|
||||||
*paletteType = PAL_BITFIELDS;
|
*paletteType = PAL_BITFIELDS;
|
||||||
RedMask = 0xf800;
|
RedMask = 0xf800;
|
||||||
GreenMask = 0x07e0;
|
GreenMask = 0x07e0;
|
||||||
|
@ -1333,6 +1391,7 @@ BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//DPRINT1("else\n");
|
||||||
*paletteType = PAL_BGR;
|
*paletteType = PAL_BGR;
|
||||||
RedMask = 0xff0000;
|
RedMask = 0xff0000;
|
||||||
GreenMask = 0x00ff00;
|
GreenMask = 0x00ff00;
|
||||||
|
@ -1350,14 +1409,17 @@ BuildDIBPalette (CONST BITMAPINFO *bmi, PINT paletteType)
|
||||||
|
|
||||||
if (PAL_INDEXED == *paletteType)
|
if (PAL_INDEXED == *paletteType)
|
||||||
{
|
{
|
||||||
|
//DPRINT1("in\n");
|
||||||
hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)bmi->bmiColors);
|
hPal = PALETTE_AllocPaletteIndexedRGB(ColorCount, (RGBQUAD*)bmi->bmiColors);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//DPRINT1("out\n");
|
||||||
hPal = PALETTE_AllocPalette(*paletteType, ColorCount,
|
hPal = PALETTE_AllocPalette(*paletteType, ColorCount,
|
||||||
(ULONG*) palEntries,
|
(ULONG*) palEntries,
|
||||||
RedMask, GreenMask, BlueMask );
|
RedMask, GreenMask, BlueMask );
|
||||||
}
|
}
|
||||||
|
//DPRINT1("returning %p\n", hPal);
|
||||||
|
|
||||||
return hPal;
|
return hPal;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1031,7 +1031,8 @@ GDIOBJ_UnlockObjByPtr(PGDI_HANDLE_TABLE HandleTable, PGDIOBJ Object)
|
||||||
GdiHdr->lockline = 0;
|
GdiHdr->lockline = 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
InterlockedDecrement((PLONG)&GdiHdr->Locks);
|
if (InterlockedDecrement((PLONG)&GdiHdr->Locks) < 0)
|
||||||
|
DPRINT1("Trying to unlock non-existant object\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue