2003-05-18 17:16:18 +00:00
|
|
|
/*
|
2011-09-20 19:41:33 +00:00
|
|
|
* COPYRIGHT: GNU GPL, See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* PURPOSE: Bitmap functions
|
2015-06-09 17:43:00 +00:00
|
|
|
* FILE: win32ss/gdi/ntgdi/bitmaps.c
|
2019-01-27 06:32:52 +00:00
|
|
|
* PROGRAMERS: Timo Kreuzer <timo.kreuzer@reactos.org>
|
|
|
|
* Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
|
2003-05-18 17:16:18 +00:00
|
|
|
*/
|
2005-06-29 07:09:25 +00:00
|
|
|
|
2010-04-26 13:58:46 +00:00
|
|
|
#include <win32k.h>
|
1999-07-02 00:54:01 +00:00
|
|
|
|
2005-06-29 07:09:25 +00:00
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
2015-03-08 13:44:24 +00:00
|
|
|
BOOL
|
|
|
|
NTAPI
|
|
|
|
GreSetBitmapOwner(
|
|
|
|
_In_ HBITMAP hbmp,
|
|
|
|
_In_ ULONG ulOwner)
|
|
|
|
{
|
|
|
|
/* Check if we have the correct object type */
|
|
|
|
if (GDI_HANDLE_GET_TYPE(hbmp) != GDILoObjType_LO_BITMAP_TYPE)
|
|
|
|
{
|
|
|
|
DPRINT1("Incorrect type for hbmp: %p\n", hbmp);
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// FIXME: this is a hack and doesn't handle a race condition properly.
|
|
|
|
/// It needs to be done in GDIOBJ_vSetObjectOwner atomically.
|
|
|
|
|
|
|
|
/* Check if we set public or none */
|
|
|
|
if ((ulOwner == GDI_OBJ_HMGR_PUBLIC) ||
|
|
|
|
(ulOwner == GDI_OBJ_HMGR_NONE))
|
|
|
|
{
|
|
|
|
/* Only allow this for owned objects */
|
|
|
|
if (GreGetObjectOwner(hbmp) != GDI_OBJ_HMGR_POWNED)
|
|
|
|
{
|
|
|
|
DPRINT1("Cannot change owner for non-powned hbmp\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return GreSetObjectOwner(hbmp, ulOwner);
|
|
|
|
}
|
|
|
|
|
2019-01-27 06:32:52 +00:00
|
|
|
LONG
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
NTAPI
|
|
|
|
UnsafeSetBitmapBits(
|
2016-01-03 16:16:04 +00:00
|
|
|
_Inout_ PSURFACE psurf,
|
|
|
|
_In_ ULONG cjBits,
|
|
|
|
_In_ const VOID *pvBits)
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
{
|
2016-01-03 16:16:04 +00:00
|
|
|
PUCHAR pjDst;
|
|
|
|
const UCHAR *pjSrc;
|
2019-01-29 03:04:46 +00:00
|
|
|
LONG lDeltaDst, lDeltaSrc, lDeltaDstAbs;
|
2019-01-27 06:32:52 +00:00
|
|
|
ULONG Y, iSrc, iDst, cbSrc, cbDst, nWidth, nHeight, cBitsPixel;
|
|
|
|
|
2015-03-08 23:36:36 +00:00
|
|
|
NT_ASSERT(psurf->flags & API_BITMAP);
|
|
|
|
NT_ASSERT(psurf->SurfObj.iBitmapFormat <= BMF_32BPP);
|
2009-03-17 06:34:09 +00:00
|
|
|
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
nWidth = psurf->SurfObj.sizlBitmap.cx;
|
2019-07-21 12:39:05 +00:00
|
|
|
nHeight = psurf->SurfObj.sizlBitmap.cy;
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
|
2009-03-17 06:34:09 +00:00
|
|
|
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
pjDst = psurf->SurfObj.pvScan0;
|
|
|
|
pjSrc = pvBits;
|
|
|
|
lDeltaDst = psurf->SurfObj.lDelta;
|
2019-01-29 03:04:46 +00:00
|
|
|
lDeltaDstAbs = labs(lDeltaDst);
|
2010-09-01 16:52:23 +00:00
|
|
|
lDeltaSrc = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
|
2019-01-29 03:04:46 +00:00
|
|
|
NT_ASSERT(lDeltaSrc <= lDeltaDstAbs);
|
2009-03-17 06:34:09 +00:00
|
|
|
|
2019-01-29 03:04:46 +00:00
|
|
|
cbDst = lDeltaDstAbs * nHeight;
|
2019-01-27 06:32:52 +00:00
|
|
|
cbSrc = lDeltaSrc * nHeight;
|
|
|
|
cjBits = min(cjBits, cbSrc);
|
2015-02-17 20:41:51 +00:00
|
|
|
|
2019-01-27 06:32:52 +00:00
|
|
|
iSrc = iDst = 0;
|
|
|
|
for (Y = 0; Y < nHeight; Y++)
|
2009-03-17 06:34:09 +00:00
|
|
|
{
|
2019-01-29 03:04:46 +00:00
|
|
|
if (iSrc + lDeltaSrc > cjBits || iDst + lDeltaDstAbs > cbDst)
|
2019-01-27 06:32:52 +00:00
|
|
|
{
|
|
|
|
LONG lDelta = min(cjBits - iSrc, cbDst - iDst);
|
|
|
|
NT_ASSERT(lDelta >= 0);
|
|
|
|
RtlCopyMemory(pjDst, pjSrc, lDelta);
|
|
|
|
iSrc += lDelta;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
/* Copy one line */
|
2019-01-27 06:32:52 +00:00
|
|
|
RtlCopyMemory(pjDst, pjSrc, lDeltaSrc);
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
pjSrc += lDeltaSrc;
|
|
|
|
pjDst += lDeltaDst;
|
2019-01-27 06:32:52 +00:00
|
|
|
iSrc += lDeltaSrc;
|
2019-01-29 03:04:46 +00:00
|
|
|
iDst += lDeltaDstAbs;
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
|
|
|
|
2019-01-27 06:32:52 +00:00
|
|
|
return iSrc;
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
HBITMAP
|
2012-01-12 14:42:59 +00:00
|
|
|
NTAPI
|
2010-06-07 15:55:03 +00:00
|
|
|
GreCreateBitmapEx(
|
2012-01-12 14:42:59 +00:00
|
|
|
_In_ ULONG nWidth,
|
|
|
|
_In_ ULONG nHeight,
|
|
|
|
_In_ ULONG cjWidthBytes,
|
|
|
|
_In_ ULONG iFormat,
|
|
|
|
_In_ USHORT fjBitmap,
|
|
|
|
_In_ ULONG cjSizeImage,
|
|
|
|
_In_opt_ PVOID pvBits,
|
|
|
|
_In_ FLONG flags)
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
{
|
|
|
|
PSURFACE psurf;
|
|
|
|
HBITMAP hbmp;
|
2012-05-01 12:59:37 +00:00
|
|
|
PVOID pvCompressedBits = NULL;
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
|
|
|
|
/* Verify format */
|
|
|
|
if (iFormat < BMF_1BPP || iFormat > BMF_PNG) return NULL;
|
|
|
|
|
2012-05-01 12:14:10 +00:00
|
|
|
/* The infamous RLE hack */
|
|
|
|
if ((iFormat == BMF_4RLE) || (iFormat == BMF_8RLE))
|
|
|
|
{
|
|
|
|
pvCompressedBits = pvBits;
|
|
|
|
pvBits = NULL;
|
|
|
|
iFormat = (iFormat == BMF_4RLE) ? BMF_4BPP : BMF_8BPP;
|
|
|
|
}
|
|
|
|
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
/* Allocate a surface */
|
2012-05-01 12:14:10 +00:00
|
|
|
psurf = SURFACE_AllocSurface(STYPE_BITMAP,
|
|
|
|
nWidth,
|
|
|
|
nHeight,
|
|
|
|
iFormat,
|
|
|
|
fjBitmap,
|
|
|
|
cjWidthBytes,
|
2015-10-31 20:37:20 +00:00
|
|
|
pvCompressedBits ? 0 : cjSizeImage,
|
2012-05-01 12:14:10 +00:00
|
|
|
pvBits);
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
if (!psurf)
|
2009-03-17 06:34:09 +00:00
|
|
|
{
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
DPRINT1("SURFACE_AllocSurface failed.\n");
|
2009-03-17 06:34:09 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
/* The infamous RLE hack */
|
2012-05-01 13:57:18 +00:00
|
|
|
if (pvCompressedBits)
|
2009-03-17 06:34:09 +00:00
|
|
|
{
|
2011-03-07 09:53:03 +00:00
|
|
|
SIZEL sizl;
|
|
|
|
LONG lDelta;
|
|
|
|
|
2010-10-24 23:40:23 +00:00
|
|
|
sizl.cx = nWidth;
|
|
|
|
sizl.cy = nHeight;
|
2011-03-07 09:53:03 +00:00
|
|
|
lDelta = WIDTH_BYTES_ALIGN32(nWidth, gajBitsPerFormat[iFormat]);
|
|
|
|
|
2012-05-01 12:14:10 +00:00
|
|
|
pvBits = psurf->SurfObj.pvBits;
|
2015-10-31 20:37:20 +00:00
|
|
|
DecompressBitmap(sizl, pvCompressedBits, pvBits, lDelta, iFormat, cjSizeImage);
|
2010-05-14 18:51:48 +00:00
|
|
|
}
|
|
|
|
|
2012-05-01 12:14:10 +00:00
|
|
|
/* Get the handle for the bitmap */
|
|
|
|
hbmp = (HBITMAP)psurf->SurfObj.hsurf;
|
|
|
|
|
2011-03-07 09:53:03 +00:00
|
|
|
/* Mark as API bitmap */
|
|
|
|
psurf->flags |= (flags | API_BITMAP);
|
2010-08-02 00:53:25 +00:00
|
|
|
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
/* Unlock the surface and return */
|
|
|
|
SURFACE_UnlockSurface(psurf);
|
|
|
|
return hbmp;
|
2004-03-22 20:46:33 +00:00
|
|
|
}
|
|
|
|
|
2010-08-02 00:53:25 +00:00
|
|
|
/* Creates a DDB surface,
|
|
|
|
* as in CreateCompatibleBitmap or CreateBitmap.
|
2011-05-24 16:23:36 +00:00
|
|
|
* Note that each scanline must be 32bit aligned!
|
2010-08-02 00:53:25 +00:00
|
|
|
*/
|
2010-06-07 15:55:03 +00:00
|
|
|
HBITMAP
|
2012-01-12 14:42:59 +00:00
|
|
|
NTAPI
|
2010-06-07 15:55:03 +00:00
|
|
|
GreCreateBitmap(
|
2012-01-12 14:42:59 +00:00
|
|
|
_In_ ULONG nWidth,
|
|
|
|
_In_ ULONG nHeight,
|
|
|
|
_In_ ULONG cPlanes,
|
|
|
|
_In_ ULONG cBitsPixel,
|
|
|
|
_In_opt_ PVOID pvBits)
|
2010-06-07 15:55:03 +00:00
|
|
|
{
|
|
|
|
/* Call the extended function */
|
2011-05-24 15:35:30 +00:00
|
|
|
return GreCreateBitmapEx(nWidth,
|
2010-06-07 15:55:03 +00:00
|
|
|
nHeight,
|
2011-12-14 04:07:06 +00:00
|
|
|
0, /* Auto width */
|
2010-06-07 15:55:03 +00:00
|
|
|
BitmapFormat(cBitsPixel * cPlanes, BI_RGB),
|
2011-12-14 04:07:06 +00:00
|
|
|
0, /* No bitmap flags */
|
|
|
|
0, /* Auto size */
|
2011-05-24 15:35:30 +00:00
|
|
|
pvBits,
|
2011-05-21 06:34:02 +00:00
|
|
|
DDB_SURFACE /* DDB */);
|
2010-06-07 15:55:03 +00:00
|
|
|
}
|
|
|
|
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
HBITMAP
|
|
|
|
APIENTRY
|
2007-08-14 23:22:07 +00:00
|
|
|
NtGdiCreateBitmap(
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
IN INT nWidth,
|
|
|
|
IN INT nHeight,
|
|
|
|
IN UINT cPlanes,
|
|
|
|
IN UINT cBitsPixel,
|
2007-08-14 23:22:07 +00:00
|
|
|
IN OPTIONAL LPBYTE pUnsafeBits)
|
|
|
|
{
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
HBITMAP hbmp;
|
2014-05-17 22:33:42 +00:00
|
|
|
ULONG cRealBpp, cjWidthBytes, iFormat;
|
2011-01-09 18:38:41 +00:00
|
|
|
ULONGLONG cjSize;
|
2012-05-01 12:14:10 +00:00
|
|
|
PSURFACE psurf;
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
|
2011-01-09 18:38:41 +00:00
|
|
|
/* Calculate bitmap format and real bits per pixel. */
|
|
|
|
iFormat = BitmapFormat(cBitsPixel * cPlanes, BI_RGB);
|
|
|
|
cRealBpp = gajBitsPerFormat[iFormat];
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
|
2011-01-09 18:38:41 +00:00
|
|
|
/* Calculate width and image size in bytes */
|
|
|
|
cjWidthBytes = WIDTH_BYTES_ALIGN16(nWidth, cRealBpp);
|
2012-03-04 11:32:43 +00:00
|
|
|
cjSize = (ULONGLONG)cjWidthBytes * nHeight;
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
|
2012-03-04 11:32:43 +00:00
|
|
|
/* Check parameters (possible overflow of cjSize!) */
|
|
|
|
if ((iFormat == 0) || (nWidth <= 0) || (nWidth >= 0x8000000) || (nHeight <= 0) ||
|
|
|
|
(cBitsPixel > 32) || (cPlanes > 32) || (cjSize >= 0x100000000ULL))
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
{
|
2012-07-31 18:40:52 +00:00
|
|
|
DPRINT1("Invalid bitmap format! Width=%d, Height=%d, Bpp=%u, Planes=%u\n",
|
2011-01-09 18:38:41 +00:00
|
|
|
nWidth, nHeight, cBitsPixel, cPlanes);
|
2010-12-25 11:01:14 +00:00
|
|
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
2010-12-24 20:29:25 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2012-05-01 12:14:10 +00:00
|
|
|
/* Allocate the surface (but don't set the bits) */
|
|
|
|
psurf = SURFACE_AllocSurface(STYPE_BITMAP,
|
|
|
|
nWidth,
|
|
|
|
nHeight,
|
|
|
|
iFormat,
|
2014-05-17 22:33:42 +00:00
|
|
|
0,
|
2012-05-01 12:14:10 +00:00
|
|
|
0,
|
2015-03-08 17:25:44 +00:00
|
|
|
0,
|
2012-05-01 12:14:10 +00:00
|
|
|
NULL);
|
|
|
|
if (!psurf)
|
|
|
|
{
|
|
|
|
DPRINT1("SURFACE_AllocSurface failed.\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Mark as API and DDB bitmap */
|
|
|
|
psurf->flags |= (API_BITMAP | DDB_SURFACE);
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
|
2012-05-01 12:14:10 +00:00
|
|
|
/* Check if we have bits to set */
|
|
|
|
if (pUnsafeBits)
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
{
|
2012-05-01 12:14:10 +00:00
|
|
|
/* Protect with SEH and copy the bits */
|
2009-03-17 06:34:09 +00:00
|
|
|
_SEH2_TRY
|
|
|
|
{
|
2012-03-04 11:32:43 +00:00
|
|
|
ProbeForRead(pUnsafeBits, (SIZE_T)cjSize, 1);
|
2015-03-08 23:36:36 +00:00
|
|
|
UnsafeSetBitmapBits(psurf, cjSize, pUnsafeBits);
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
[WIN32K]
Rewrite of the GDI handle manager
- The old handle manager used a completely retarded spinlock in combination with KeDelayExecutionThread() for both exclusive
and shared locks. This is probably the most uneffective algorithm possible. It was also duplicating code everywhere and it was a overall mess It
is now replaced with a lock-free reference counter for shared locks and a pushlock for exclusive locks. -> Better performance and scalability.
- Allocate user mode object attributes from the new gdi pool. This way, we don't need any caching, since the pool serves as a cache. Its also
much faster and uses much less memory.
- Allow object allocations of different size, instead of fixed size from a table. This way a single allocation can take care of actual needs.
- Allow allcoating objects without a handle and insert them into the handle table later
- Properly synchronize the process GDIHandleCount. Now gdiview and taskmanager show the correct number of gdi handles.
- Implement a new event tracking system, that is capable of tracking all reverences and locks of objects and pool allocations to help track
possible leaks
- Make sure that all objects of a process are deleted in cleanup
- Make sure all usermode memory allocations are freed, when cleaning up the process pool.
- Make sure that each object type is using the correct type of lock (either shared or exclusive, not a mixture)
- Fix some object / reference leaks
- Lots of inferface improvements
- Use global variables for certain things instead of members in the mapped gdi handle table
- Make IntSysCreateRectpRgn create a region without a handle
- Fix detection od source and mask use in GreStretchBltMask
- Use GDIOBJ_bLockMultipleObjects in NtGdiCombineRegion to avoid possible deadlocks
- Fix NtGdiAbortPath to reset DCPATH_ACTIVE flag in the dc and only bail out on error, instead of always
- Replace DC_AllocateDcAttr and DC_AllocDcAttr with DC_bAllocDcAttr using the new user mode pool
- Remove DCU_SyncDcAttrtoUser and DCU_SynchDcAttrtoUser. Those functions were unused and didn't do anything useful anyway,
- Replace IntGdiSetDCOwnerEx and DC_SetOwnership with GreSetDCOwner, remove unused NoSetBrush parameter
- Replace GDIOBJ_bValidateHandle and IsObjectDead with GreIsHandleValid
- Chage GDIOBJ_bLockMultipleObjects: pass object type, return a BOOL, whether all objects could be locked, cleanup on failure
svn path=/trunk/; revision=51470
2011-04-28 08:26:46 +00:00
|
|
|
GDIOBJ_vDeleteObject(&psurf->BaseObject);
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
_SEH2_YIELD(return NULL;)
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
|
|
|
_SEH2_END
|
2012-05-01 12:14:10 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Zero the bits */
|
|
|
|
RtlZeroMemory(psurf->SurfObj.pvBits, psurf->SurfObj.cjBits);
|
2010-08-02 00:53:25 +00:00
|
|
|
}
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
|
2012-05-01 12:14:10 +00:00
|
|
|
/* Get the handle for the bitmap */
|
|
|
|
hbmp = (HBITMAP)psurf->SurfObj.hsurf;
|
|
|
|
|
|
|
|
/* Unlock the surface */
|
|
|
|
SURFACE_UnlockSurface(psurf);
|
|
|
|
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
return hbmp;
|
2007-08-14 23:22:07 +00:00
|
|
|
}
|
|
|
|
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
|
2004-03-15 22:06:55 +00:00
|
|
|
HBITMAP FASTCALL
|
2004-03-22 20:46:33 +00:00
|
|
|
IntCreateCompatibleBitmap(
|
2009-03-17 06:34:09 +00:00
|
|
|
PDC Dc,
|
|
|
|
INT Width,
|
2014-10-24 17:31:46 +00:00
|
|
|
INT Height,
|
|
|
|
UINT Planes,
|
|
|
|
UINT Bpp)
|
1999-07-23 19:57:18 +00:00
|
|
|
{
|
2009-03-17 06:34:09 +00:00
|
|
|
HBITMAP Bmp = NULL;
|
2012-07-01 13:43:33 +00:00
|
|
|
PPALETTE ppal;
|
2009-03-17 06:34:09 +00:00
|
|
|
|
|
|
|
/* MS doc says if width or height is 0, return 1-by-1 pixel, monochrome bitmap */
|
|
|
|
if (0 == Width || 0 == Height)
|
|
|
|
{
|
2011-03-07 22:06:23 +00:00
|
|
|
return NtGdiGetStockObject(DEFAULT_BITMAP);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Dc->dctype != DC_TYPE_MEMORY)
|
|
|
|
{
|
|
|
|
PSURFACE psurf;
|
|
|
|
|
|
|
|
Bmp = GreCreateBitmap(abs(Width),
|
|
|
|
abs(Height),
|
2014-10-24 17:31:46 +00:00
|
|
|
Planes ? Planes : 1,
|
|
|
|
Bpp ? Bpp : Dc->ppdev->gdiinfo.cBitsPixel,
|
2011-03-07 22:06:23 +00:00
|
|
|
NULL);
|
2014-10-25 21:16:17 +00:00
|
|
|
if (Bmp == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to allocate a bitmap!\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-03-07 22:06:23 +00:00
|
|
|
psurf = SURFACE_ShareLockSurface(Bmp);
|
|
|
|
ASSERT(psurf);
|
2012-07-01 13:43:33 +00:00
|
|
|
|
|
|
|
/* Dereference old palette and set new palette */
|
|
|
|
ppal = PALETTE_ShareLockPalette(Dc->ppdev->devinfo.hpalDefault);
|
|
|
|
ASSERT(ppal);
|
|
|
|
SURFACE_vSetPalette(psurf, ppal);
|
|
|
|
PALETTE_ShareUnlockPalette(ppal);
|
|
|
|
|
2011-03-07 22:06:23 +00:00
|
|
|
/* Set flags */
|
|
|
|
psurf->flags = API_BITMAP;
|
2011-12-14 04:07:06 +00:00
|
|
|
psurf->hdc = NULL; // FIXME:
|
2014-10-24 11:35:07 +00:00
|
|
|
psurf->SurfObj.hdev = (HDEV)Dc->ppdev;
|
2011-03-07 22:06:23 +00:00
|
|
|
SURFACE_ShareUnlockSurface(psurf);
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-03-07 22:06:23 +00:00
|
|
|
DIBSECTION dibs;
|
|
|
|
INT Count;
|
|
|
|
PSURFACE psurf = Dc->dclevel.pSurface;
|
2012-07-23 10:12:53 +00:00
|
|
|
if(!psurf) psurf = psurfDefaultBitmap;
|
2011-03-07 22:06:23 +00:00
|
|
|
Count = BITMAP_GetObject(psurf, sizeof(dibs), &dibs);
|
|
|
|
|
|
|
|
if (Count == sizeof(BITMAP))
|
2009-03-17 06:34:09 +00:00
|
|
|
{
|
2011-03-07 22:06:23 +00:00
|
|
|
PSURFACE psurfBmp;
|
2010-05-14 18:51:48 +00:00
|
|
|
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
Bmp = GreCreateBitmap(abs(Width),
|
2011-03-07 22:06:23 +00:00
|
|
|
abs(Height),
|
2014-10-24 17:31:46 +00:00
|
|
|
Planes ? Planes : 1,
|
|
|
|
Bpp ? Bpp : dibs.dsBm.bmBitsPixel,
|
2011-03-07 22:06:23 +00:00
|
|
|
NULL);
|
2011-04-18 19:09:05 +00:00
|
|
|
psurfBmp = SURFACE_ShareLockSurface(Bmp);
|
2011-03-07 22:06:23 +00:00
|
|
|
ASSERT(psurfBmp);
|
2012-07-01 13:43:33 +00:00
|
|
|
|
|
|
|
/* Dereference old palette and set new palette */
|
|
|
|
SURFACE_vSetPalette(psurfBmp, psurf->ppal);
|
|
|
|
|
2010-05-14 18:51:48 +00:00
|
|
|
/* Set flags */
|
2011-03-07 22:06:23 +00:00
|
|
|
psurfBmp->flags = API_BITMAP;
|
2011-12-14 04:07:06 +00:00
|
|
|
psurfBmp->hdc = NULL; // FIXME:
|
2014-10-24 11:35:07 +00:00
|
|
|
psurf->SurfObj.hdev = (HDEV)Dc->ppdev;
|
2011-04-18 19:09:05 +00:00
|
|
|
SURFACE_ShareUnlockSurface(psurfBmp);
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
2011-03-07 22:06:23 +00:00
|
|
|
else if (Count == sizeof(DIBSECTION))
|
2008-12-01 00:13:45 +00:00
|
|
|
{
|
2011-03-07 22:06:23 +00:00
|
|
|
/* A DIB section is selected in the DC */
|
|
|
|
BYTE buf[sizeof(BITMAPINFOHEADER) + 256*sizeof(RGBQUAD)] = {0};
|
|
|
|
PVOID Bits;
|
|
|
|
BITMAPINFO* bi = (BITMAPINFO*)buf;
|
|
|
|
|
|
|
|
bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
|
|
|
|
bi->bmiHeader.biWidth = Width;
|
|
|
|
bi->bmiHeader.biHeight = Height;
|
2014-10-24 17:31:46 +00:00
|
|
|
bi->bmiHeader.biPlanes = Planes ? Planes : dibs.dsBmih.biPlanes;
|
|
|
|
bi->bmiHeader.biBitCount = Bpp ? Bpp : dibs.dsBmih.biBitCount;
|
2011-03-07 22:06:23 +00:00
|
|
|
bi->bmiHeader.biCompression = dibs.dsBmih.biCompression;
|
|
|
|
bi->bmiHeader.biSizeImage = 0;
|
|
|
|
bi->bmiHeader.biXPelsPerMeter = dibs.dsBmih.biXPelsPerMeter;
|
|
|
|
bi->bmiHeader.biYPelsPerMeter = dibs.dsBmih.biYPelsPerMeter;
|
|
|
|
bi->bmiHeader.biClrUsed = dibs.dsBmih.biClrUsed;
|
|
|
|
bi->bmiHeader.biClrImportant = dibs.dsBmih.biClrImportant;
|
|
|
|
|
|
|
|
if (bi->bmiHeader.biCompression == BI_BITFIELDS)
|
2009-03-17 06:34:09 +00:00
|
|
|
{
|
2011-03-07 22:06:23 +00:00
|
|
|
/* Copy the color masks */
|
|
|
|
RtlCopyMemory(bi->bmiColors, dibs.dsBitfields, 3*sizeof(RGBQUAD));
|
|
|
|
}
|
|
|
|
else if (bi->bmiHeader.biBitCount <= 8)
|
|
|
|
{
|
|
|
|
/* Copy the color table */
|
|
|
|
UINT Index;
|
|
|
|
PPALETTE PalGDI;
|
|
|
|
|
|
|
|
if (!psurf->ppal)
|
2009-03-17 06:34:09 +00:00
|
|
|
{
|
2011-03-07 22:06:23 +00:00
|
|
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
return 0;
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
2011-03-07 22:06:23 +00:00
|
|
|
|
[WIN32K]
Rewrite of the GDI handle manager
- The old handle manager used a completely retarded spinlock in combination with KeDelayExecutionThread() for both exclusive
and shared locks. This is probably the most uneffective algorithm possible. It was also duplicating code everywhere and it was a overall mess It
is now replaced with a lock-free reference counter for shared locks and a pushlock for exclusive locks. -> Better performance and scalability.
- Allocate user mode object attributes from the new gdi pool. This way, we don't need any caching, since the pool serves as a cache. Its also
much faster and uses much less memory.
- Allow object allocations of different size, instead of fixed size from a table. This way a single allocation can take care of actual needs.
- Allow allcoating objects without a handle and insert them into the handle table later
- Properly synchronize the process GDIHandleCount. Now gdiview and taskmanager show the correct number of gdi handles.
- Implement a new event tracking system, that is capable of tracking all reverences and locks of objects and pool allocations to help track
possible leaks
- Make sure that all objects of a process are deleted in cleanup
- Make sure all usermode memory allocations are freed, when cleaning up the process pool.
- Make sure that each object type is using the correct type of lock (either shared or exclusive, not a mixture)
- Fix some object / reference leaks
- Lots of inferface improvements
- Use global variables for certain things instead of members in the mapped gdi handle table
- Make IntSysCreateRectpRgn create a region without a handle
- Fix detection od source and mask use in GreStretchBltMask
- Use GDIOBJ_bLockMultipleObjects in NtGdiCombineRegion to avoid possible deadlocks
- Fix NtGdiAbortPath to reset DCPATH_ACTIVE flag in the dc and only bail out on error, instead of always
- Replace DC_AllocateDcAttr and DC_AllocDcAttr with DC_bAllocDcAttr using the new user mode pool
- Remove DCU_SyncDcAttrtoUser and DCU_SynchDcAttrtoUser. Those functions were unused and didn't do anything useful anyway,
- Replace IntGdiSetDCOwnerEx and DC_SetOwnership with GreSetDCOwner, remove unused NoSetBrush parameter
- Replace GDIOBJ_bValidateHandle and IsObjectDead with GreIsHandleValid
- Chage GDIOBJ_bLockMultipleObjects: pass object type, return a BOOL, whether all objects could be locked, cleanup on failure
svn path=/trunk/; revision=51470
2011-04-28 08:26:46 +00:00
|
|
|
PalGDI = psurf->ppal;
|
2011-03-07 22:06:23 +00:00
|
|
|
|
|
|
|
for (Index = 0;
|
|
|
|
Index < 256 && Index < PalGDI->NumColors;
|
|
|
|
Index++)
|
2009-03-17 06:34:09 +00:00
|
|
|
{
|
2011-03-07 22:06:23 +00:00
|
|
|
bi->bmiColors[Index].rgbRed = PalGDI->IndexedColors[Index].peRed;
|
|
|
|
bi->bmiColors[Index].rgbGreen = PalGDI->IndexedColors[Index].peGreen;
|
|
|
|
bi->bmiColors[Index].rgbBlue = PalGDI->IndexedColors[Index].peBlue;
|
|
|
|
bi->bmiColors[Index].rgbReserved = 0;
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
|
|
|
}
|
2011-03-07 22:06:23 +00:00
|
|
|
|
|
|
|
Bmp = DIB_CreateDIBSection(Dc,
|
|
|
|
bi,
|
|
|
|
DIB_RGB_COLORS,
|
|
|
|
&Bits,
|
|
|
|
NULL,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
return Bmp;
|
2008-12-01 00:13:45 +00:00
|
|
|
}
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
|
|
|
return Bmp;
|
2004-03-15 22:06:55 +00:00
|
|
|
}
|
|
|
|
|
2008-11-29 22:48:58 +00:00
|
|
|
HBITMAP APIENTRY
|
2004-03-22 20:46:33 +00:00
|
|
|
NtGdiCreateCompatibleBitmap(
|
2009-03-17 06:34:09 +00:00
|
|
|
HDC hDC,
|
|
|
|
INT Width,
|
|
|
|
INT Height)
|
2004-03-15 22:06:55 +00:00
|
|
|
{
|
2009-03-17 06:34:09 +00:00
|
|
|
HBITMAP Bmp;
|
|
|
|
PDC Dc;
|
2004-03-15 22:06:55 +00:00
|
|
|
|
2012-05-01 12:14:10 +00:00
|
|
|
/* Check parameters */
|
|
|
|
if ((Width <= 0) || (Height <= 0) || ((Width * Height) > 0x3FFFFFFF))
|
2009-03-17 06:34:09 +00:00
|
|
|
{
|
2010-12-25 11:01:14 +00:00
|
|
|
EngSetLastError(ERROR_INVALID_PARAMETER);
|
2009-03-17 06:34:09 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2008-11-21 18:34:31 +00:00
|
|
|
|
2009-03-17 06:34:09 +00:00
|
|
|
if (!hDC)
|
[WIN32K]
Rewrite the bitmap API. There were a lot of bugs. NtGdiCreateBitmap allowed a negative height, leading to either topdown or bottomup bitmaps, a behaviour that Windows doesn't have. The function copied the bitmap bits directly from the caller to the bitmap using RtlCopyMemory, ignoring different scanline length and direction (resulting in bitmaps being upside down), not SEH protected. This function (IntSetBitmapBits) is replaced by a better solution UnsafeSetBitmapBits, that takes these things into account. The name is chosen to give a hint that the function can/should be SEH protected. IntSetBitmapBits is still there, as its retarded behaviour is actually required in some places. There were also IntCreateBitmap and IntGdiCreateBitmap, now both being replaced by GreCreateBitmap. The code that set the palette is removed, as it's already done in SURFACE_AllocSurface, here gpalRGB is replaced with gpalBGR, fixing some inverted color issues. The alignment correction in SURFACE_bSetBitmapBits is reapplied, now that the callers are behaving as they are supposed to do.
svn path=/branches/reactos-yarotows/; revision=47641
2010-06-06 22:01:41 +00:00
|
|
|
return GreCreateBitmap(Width, Height, 1, 1, 0);
|
2008-12-01 00:13:45 +00:00
|
|
|
|
2009-03-17 06:34:09 +00:00
|
|
|
Dc = DC_LockDc(hDC);
|
2004-03-15 22:06:55 +00:00
|
|
|
|
2012-07-31 18:40:52 +00:00
|
|
|
DPRINT("NtGdiCreateCompatibleBitmap(%p,%d,%d, bpp:%u) = \n",
|
2009-08-16 12:57:41 +00:00
|
|
|
hDC, Width, Height, Dc->ppdev->gdiinfo.cBitsPixel);
|
2004-03-15 22:06:55 +00:00
|
|
|
|
2009-03-17 06:34:09 +00:00
|
|
|
if (NULL == Dc)
|
|
|
|
{
|
2010-12-25 11:01:14 +00:00
|
|
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
2009-03-17 06:34:09 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2004-03-15 22:06:55 +00:00
|
|
|
|
2014-10-24 17:31:46 +00:00
|
|
|
Bmp = IntCreateCompatibleBitmap(Dc, Width, Height, 0, 0);
|
2004-03-15 22:06:55 +00:00
|
|
|
|
2009-03-17 06:34:09 +00:00
|
|
|
DC_UnlockDc(Dc);
|
|
|
|
return Bmp;
|
1999-07-23 19:57:18 +00:00
|
|
|
}
|
|
|
|
|
2012-05-01 12:14:10 +00:00
|
|
|
BOOL
|
2017-01-09 21:12:00 +00:00
|
|
|
NTAPI
|
|
|
|
GreGetBitmapDimension(
|
|
|
|
_In_ HBITMAP hBitmap,
|
|
|
|
_Out_ LPSIZE psizDim)
|
1999-07-02 02:06:52 +00:00
|
|
|
{
|
2009-03-17 06:34:09 +00:00
|
|
|
PSURFACE psurfBmp;
|
|
|
|
|
|
|
|
if (hBitmap == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
2012-05-01 12:14:10 +00:00
|
|
|
/* Lock the bitmap */
|
2011-04-18 19:09:05 +00:00
|
|
|
psurfBmp = SURFACE_ShareLockSurface(hBitmap);
|
2009-03-17 06:34:09 +00:00
|
|
|
if (psurfBmp == NULL)
|
|
|
|
{
|
2010-12-25 11:01:14 +00:00
|
|
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
2009-03-17 06:34:09 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2017-01-09 21:12:00 +00:00
|
|
|
*psizDim = psurfBmp->sizlDim;
|
|
|
|
|
|
|
|
/* Unlock the bitmap */
|
|
|
|
SURFACE_ShareUnlockSurface(psurfBmp);
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
|
|
APIENTRY
|
|
|
|
NtGdiGetBitmapDimension(
|
|
|
|
HBITMAP hBitmap,
|
|
|
|
LPSIZE psizDim)
|
|
|
|
{
|
|
|
|
SIZE dim;
|
|
|
|
|
|
|
|
if (!GreGetBitmapDimension(hBitmap, &dim))
|
|
|
|
return FALSE;
|
|
|
|
|
2012-05-01 12:14:10 +00:00
|
|
|
/* Use SEH to copy the data to the caller */
|
2009-03-17 06:34:09 +00:00
|
|
|
_SEH2_TRY
|
|
|
|
{
|
2017-01-09 21:12:00 +00:00
|
|
|
ProbeForWrite(psizDim, sizeof(*psizDim), 1);
|
|
|
|
*psizDim = dim;
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
2017-01-09 21:12:00 +00:00
|
|
|
_SEH2_YIELD(return FALSE);
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
|
|
|
_SEH2_END
|
|
|
|
|
2017-01-09 21:12:00 +00:00
|
|
|
return TRUE;
|
1999-07-02 02:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-01-27 06:51:33 +00:00
|
|
|
LONG
|
2010-08-02 16:49:51 +00:00
|
|
|
FASTCALL
|
|
|
|
UnsafeGetBitmapBits(
|
|
|
|
PSURFACE psurf,
|
2012-01-12 14:42:59 +00:00
|
|
|
DWORD Bytes,
|
|
|
|
OUT PBYTE pvBits)
|
2010-08-02 16:49:51 +00:00
|
|
|
{
|
2012-01-12 14:42:59 +00:00
|
|
|
PUCHAR pjDst, pjSrc;
|
2019-01-29 03:04:46 +00:00
|
|
|
LONG lDeltaDst, lDeltaSrc, lDeltaSrcAbs;
|
2019-01-27 06:51:33 +00:00
|
|
|
ULONG Y, iSrc, iDst, cbSrc, cbDst, nWidth, nHeight, cBitsPixel;
|
2010-08-02 16:49:51 +00:00
|
|
|
|
|
|
|
nWidth = psurf->SurfObj.sizlBitmap.cx;
|
2019-07-21 12:39:05 +00:00
|
|
|
nHeight = psurf->SurfObj.sizlBitmap.cy;
|
2010-08-02 16:49:51 +00:00
|
|
|
cBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
|
|
|
|
|
|
|
|
/* Get pointers */
|
|
|
|
pjSrc = psurf->SurfObj.pvScan0;
|
|
|
|
pjDst = pvBits;
|
|
|
|
lDeltaSrc = psurf->SurfObj.lDelta;
|
2019-01-29 03:04:46 +00:00
|
|
|
lDeltaSrcAbs = labs(lDeltaSrc);
|
2010-09-01 16:52:23 +00:00
|
|
|
lDeltaDst = WIDTH_BYTES_ALIGN16(nWidth, cBitsPixel);
|
2019-01-29 03:04:46 +00:00
|
|
|
NT_ASSERT(lDeltaSrcAbs >= lDeltaDst);
|
2019-01-27 06:51:33 +00:00
|
|
|
|
2019-01-29 03:04:46 +00:00
|
|
|
cbSrc = nHeight * lDeltaSrcAbs;
|
2019-01-27 06:51:33 +00:00
|
|
|
cbDst = nHeight * lDeltaDst;
|
|
|
|
Bytes = min(Bytes, cbDst);
|
2010-08-02 16:49:51 +00:00
|
|
|
|
2019-01-27 06:51:33 +00:00
|
|
|
iSrc = iDst = 0;
|
|
|
|
for (Y = 0; Y < nHeight; Y++)
|
2010-08-02 16:49:51 +00:00
|
|
|
{
|
2019-01-29 03:04:46 +00:00
|
|
|
if (iSrc + lDeltaSrcAbs > cbSrc || iDst + lDeltaDst > Bytes)
|
2019-01-27 06:51:33 +00:00
|
|
|
{
|
|
|
|
LONG lDelta = min(cbSrc - iSrc, Bytes - iDst);
|
|
|
|
NT_ASSERT(lDelta >= 0);
|
|
|
|
RtlCopyMemory(pjDst, pjSrc, lDelta);
|
|
|
|
iDst += lDelta;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-08-02 16:49:51 +00:00
|
|
|
/* Copy one line */
|
|
|
|
RtlCopyMemory(pjDst, pjSrc, lDeltaDst);
|
|
|
|
pjSrc += lDeltaSrc;
|
|
|
|
pjDst += lDeltaDst;
|
2019-01-29 03:04:46 +00:00
|
|
|
iSrc += lDeltaSrcAbs;
|
2019-01-27 06:51:33 +00:00
|
|
|
iDst += lDeltaDst;
|
2010-08-02 16:49:51 +00:00
|
|
|
}
|
2019-01-27 06:51:33 +00:00
|
|
|
|
|
|
|
return iDst;
|
2010-08-02 16:49:51 +00:00
|
|
|
}
|
|
|
|
|
2012-01-12 14:42:59 +00:00
|
|
|
LONG
|
|
|
|
APIENTRY
|
2009-03-17 06:34:09 +00:00
|
|
|
NtGdiGetBitmapBits(
|
|
|
|
HBITMAP hBitmap,
|
2012-01-12 14:42:59 +00:00
|
|
|
ULONG cjBuffer,
|
2009-03-17 06:34:09 +00:00
|
|
|
OUT OPTIONAL PBYTE pUnsafeBits)
|
2007-08-02 22:14:32 +00:00
|
|
|
{
|
2009-03-17 06:34:09 +00:00
|
|
|
PSURFACE psurf;
|
2012-01-12 14:42:59 +00:00
|
|
|
ULONG cjSize;
|
|
|
|
LONG ret;
|
2009-03-17 06:34:09 +00:00
|
|
|
|
2012-01-12 14:42:59 +00:00
|
|
|
/* Check parameters */
|
|
|
|
if (pUnsafeBits != NULL && cjBuffer == 0)
|
2009-03-17 06:34:09 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-01-12 14:42:59 +00:00
|
|
|
/* Lock the bitmap */
|
2011-04-18 19:09:05 +00:00
|
|
|
psurf = SURFACE_ShareLockSurface(hBitmap);
|
2009-03-17 06:34:09 +00:00
|
|
|
if (!psurf)
|
|
|
|
{
|
2010-12-25 11:01:14 +00:00
|
|
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
2009-03-17 06:34:09 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-01-12 14:42:59 +00:00
|
|
|
/* Calculate the size of the bitmap in bytes */
|
|
|
|
cjSize = WIDTH_BYTES_ALIGN16(psurf->SurfObj.sizlBitmap.cx,
|
|
|
|
BitsPerFormat(psurf->SurfObj.iBitmapFormat)) *
|
2019-07-21 12:39:05 +00:00
|
|
|
psurf->SurfObj.sizlBitmap.cy;
|
2009-08-04 20:37:10 +00:00
|
|
|
|
2009-03-17 06:34:09 +00:00
|
|
|
/* If the bits vector is null, the function should return the read size */
|
|
|
|
if (pUnsafeBits == NULL)
|
|
|
|
{
|
2011-04-18 19:09:05 +00:00
|
|
|
SURFACE_ShareUnlockSurface(psurf);
|
2012-01-12 14:42:59 +00:00
|
|
|
return cjSize;
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Don't copy more bytes than the buffer has */
|
2012-01-12 14:42:59 +00:00
|
|
|
cjBuffer = min(cjBuffer, cjSize);
|
2009-03-17 06:34:09 +00:00
|
|
|
|
2011-12-14 04:07:06 +00:00
|
|
|
// FIXME: Use MmSecureVirtualMemory
|
2009-03-17 06:34:09 +00:00
|
|
|
_SEH2_TRY
|
|
|
|
{
|
2012-01-12 14:42:59 +00:00
|
|
|
ProbeForWrite(pUnsafeBits, cjBuffer, 1);
|
2019-01-27 06:51:33 +00:00
|
|
|
ret = UnsafeGetBitmapBits(psurf, cjBuffer, pUnsafeBits);
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
_SEH2_END
|
|
|
|
|
2011-04-18 19:09:05 +00:00
|
|
|
SURFACE_ShareUnlockSurface(psurf);
|
2009-03-17 06:34:09 +00:00
|
|
|
|
|
|
|
return ret;
|
2007-08-02 22:14:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-11-29 22:48:58 +00:00
|
|
|
LONG APIENTRY
|
2007-08-02 22:14:32 +00:00
|
|
|
NtGdiSetBitmapBits(
|
2009-03-17 06:34:09 +00:00
|
|
|
HBITMAP hBitmap,
|
|
|
|
DWORD Bytes,
|
|
|
|
IN PBYTE pUnsafeBits)
|
2007-08-02 22:14:32 +00:00
|
|
|
{
|
2009-03-17 06:34:09 +00:00
|
|
|
LONG ret;
|
|
|
|
PSURFACE psurf;
|
|
|
|
|
|
|
|
if (pUnsafeBits == NULL || Bytes == 0)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-03-08 23:36:36 +00:00
|
|
|
if (GDI_HANDLE_IS_STOCKOBJ(hBitmap))
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-04-18 19:09:05 +00:00
|
|
|
psurf = SURFACE_ShareLockSurface(hBitmap);
|
2009-03-17 06:34:09 +00:00
|
|
|
if (psurf == NULL)
|
|
|
|
{
|
2010-12-25 11:01:14 +00:00
|
|
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
2009-03-17 06:34:09 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-03-08 23:36:36 +00:00
|
|
|
if (((psurf->flags & API_BITMAP) == 0) ||
|
|
|
|
(psurf->SurfObj.iBitmapFormat > BMF_32BPP))
|
|
|
|
{
|
|
|
|
DPRINT1("Invalid bitmap: iBitmapFormat = %lu, flags = 0x%lx\n",
|
|
|
|
psurf->SurfObj.iBitmapFormat,
|
|
|
|
psurf->flags);
|
|
|
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
|
|
|
SURFACE_ShareUnlockSurface(psurf);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-03-17 06:34:09 +00:00
|
|
|
_SEH2_TRY
|
|
|
|
{
|
2019-01-27 07:11:23 +00:00
|
|
|
/* NOTE: Win2k3 doesn't check WORD alignment here. */
|
2019-01-30 07:54:45 +00:00
|
|
|
ProbeForWrite(pUnsafeBits, Bytes, 1);
|
2015-02-17 20:41:51 +00:00
|
|
|
ret = UnsafeSetBitmapBits(psurf, Bytes, pUnsafeBits);
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
ret = 0;
|
|
|
|
}
|
|
|
|
_SEH2_END
|
|
|
|
|
2011-04-18 19:09:05 +00:00
|
|
|
SURFACE_ShareUnlockSurface(psurf);
|
2009-03-17 06:34:09 +00:00
|
|
|
|
|
|
|
return ret;
|
1999-07-02 02:06:52 +00:00
|
|
|
}
|
|
|
|
|
2008-11-29 22:48:58 +00:00
|
|
|
BOOL APIENTRY
|
2007-08-11 06:29:31 +00:00
|
|
|
NtGdiSetBitmapDimension(
|
2009-03-17 06:34:09 +00:00
|
|
|
HBITMAP hBitmap,
|
|
|
|
INT Width,
|
|
|
|
INT Height,
|
|
|
|
LPSIZE Size)
|
1999-07-02 02:06:52 +00:00
|
|
|
{
|
2009-03-17 06:34:09 +00:00
|
|
|
PSURFACE psurf;
|
|
|
|
BOOL Ret = TRUE;
|
|
|
|
|
|
|
|
if (hBitmap == NULL)
|
|
|
|
return FALSE;
|
|
|
|
|
2011-04-18 19:09:05 +00:00
|
|
|
psurf = SURFACE_ShareLockSurface(hBitmap);
|
2009-03-17 06:34:09 +00:00
|
|
|
if (psurf == NULL)
|
|
|
|
{
|
2010-12-25 11:01:14 +00:00
|
|
|
EngSetLastError(ERROR_INVALID_HANDLE);
|
2009-03-17 06:34:09 +00:00
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Size)
|
|
|
|
{
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
ProbeForWrite(Size, sizeof(SIZE), 1);
|
2010-06-05 21:19:41 +00:00
|
|
|
*Size = psurf->sizlDim;
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
Ret = FALSE;
|
|
|
|
}
|
|
|
|
_SEH2_END
|
|
|
|
}
|
|
|
|
|
|
|
|
/* The dimension is changed even if writing the old value failed */
|
2010-06-05 21:19:41 +00:00
|
|
|
psurf->sizlDim.cx = Width;
|
|
|
|
psurf->sizlDim.cy = Height;
|
2009-03-17 06:34:09 +00:00
|
|
|
|
2011-04-18 19:09:05 +00:00
|
|
|
SURFACE_ShareUnlockSurface(psurf);
|
2009-03-17 06:34:09 +00:00
|
|
|
|
|
|
|
return Ret;
|
1999-07-02 02:06:52 +00:00
|
|
|
}
|
|
|
|
|
1999-10-29 01:58:20 +00:00
|
|
|
/* Internal Functions */
|
|
|
|
|
2012-01-12 14:42:59 +00:00
|
|
|
HBITMAP
|
|
|
|
FASTCALL
|
2009-03-17 06:34:09 +00:00
|
|
|
BITMAP_CopyBitmap(HBITMAP hBitmap)
|
1999-11-17 20:54:05 +00:00
|
|
|
{
|
2012-01-12 14:42:59 +00:00
|
|
|
HBITMAP hbmNew;
|
|
|
|
SURFACE *psurfSrc, *psurfNew;
|
2009-03-17 06:34:09 +00:00
|
|
|
|
2012-01-12 14:42:59 +00:00
|
|
|
/* Fail, if no source bitmap is given */
|
|
|
|
if (hBitmap == NULL) return 0;
|
2009-03-17 06:34:09 +00:00
|
|
|
|
2012-01-12 14:42:59 +00:00
|
|
|
/* Lock the source bitmap */
|
|
|
|
psurfSrc = SURFACE_ShareLockSurface(hBitmap);
|
|
|
|
if (psurfSrc == NULL)
|
2009-03-17 06:34:09 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-01-12 14:42:59 +00:00
|
|
|
/* Allocate a new bitmap with the same dimensions as the source bmp */
|
|
|
|
hbmNew = GreCreateBitmapEx(psurfSrc->SurfObj.sizlBitmap.cx,
|
|
|
|
psurfSrc->SurfObj.sizlBitmap.cy,
|
2012-01-12 15:41:56 +00:00
|
|
|
abs(psurfSrc->SurfObj.lDelta),
|
2012-01-12 14:42:59 +00:00
|
|
|
psurfSrc->SurfObj.iBitmapFormat,
|
2012-05-01 12:14:10 +00:00
|
|
|
psurfSrc->SurfObj.fjBitmap & BMF_TOPDOWN,
|
2012-01-12 14:42:59 +00:00
|
|
|
psurfSrc->SurfObj.cjBits,
|
|
|
|
NULL,
|
|
|
|
psurfSrc->flags);
|
2009-03-17 06:34:09 +00:00
|
|
|
|
2012-01-12 14:42:59 +00:00
|
|
|
if (hbmNew)
|
2009-03-17 06:34:09 +00:00
|
|
|
{
|
2012-01-12 14:42:59 +00:00
|
|
|
/* Lock the new bitmap */
|
|
|
|
psurfNew = SURFACE_ShareLockSurface(hbmNew);
|
|
|
|
if (psurfNew)
|
2009-03-17 06:34:09 +00:00
|
|
|
{
|
2012-01-12 14:42:59 +00:00
|
|
|
/* Copy the bitmap bits to the new bitmap buffer */
|
|
|
|
RtlCopyMemory(psurfNew->SurfObj.pvBits,
|
|
|
|
psurfSrc->SurfObj.pvBits,
|
|
|
|
psurfNew->SurfObj.cjBits);
|
|
|
|
|
|
|
|
|
|
|
|
/* Reference the palette of the source bitmap and use it */
|
2012-07-01 13:43:33 +00:00
|
|
|
SURFACE_vSetPalette(psurfNew, psurfSrc->ppal);
|
2012-01-12 14:42:59 +00:00
|
|
|
|
|
|
|
/* Unlock the new surface */
|
|
|
|
SURFACE_ShareUnlockSurface(psurfNew);
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2012-01-12 14:42:59 +00:00
|
|
|
/* Failed to lock the bitmap, shouldn't happen */
|
|
|
|
GreDeleteObject(hbmNew);
|
|
|
|
hbmNew = NULL;
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-12 14:42:59 +00:00
|
|
|
/* Unlock the source bitmap and return the handle of the new bitmap */
|
|
|
|
SURFACE_ShareUnlockSurface(psurfSrc);
|
|
|
|
return hbmNew;
|
1999-11-17 20:54:05 +00:00
|
|
|
}
|
|
|
|
|
2008-11-29 22:48:58 +00:00
|
|
|
INT APIENTRY
|
2009-01-09 02:06:39 +00:00
|
|
|
BITMAP_GetObject(SURFACE *psurf, INT Count, LPVOID buffer)
|
1999-11-17 20:54:05 +00:00
|
|
|
{
|
2009-01-09 02:06:39 +00:00
|
|
|
PBITMAP pBitmap;
|
|
|
|
|
|
|
|
if (!buffer) return sizeof(BITMAP);
|
2009-03-17 06:34:09 +00:00
|
|
|
if ((UINT)Count < sizeof(BITMAP)) return 0;
|
2006-09-25 05:25:11 +00:00
|
|
|
|
2011-12-14 04:07:06 +00:00
|
|
|
/* Always fill a basic BITMAP structure */
|
2009-01-09 02:06:39 +00:00
|
|
|
pBitmap = buffer;
|
|
|
|
pBitmap->bmType = 0;
|
|
|
|
pBitmap->bmWidth = psurf->SurfObj.sizlBitmap.cx;
|
|
|
|
pBitmap->bmHeight = psurf->SurfObj.sizlBitmap.cy;
|
|
|
|
pBitmap->bmPlanes = 1;
|
|
|
|
pBitmap->bmBitsPixel = BitsPerFormat(psurf->SurfObj.iBitmapFormat);
|
2012-01-12 14:42:59 +00:00
|
|
|
pBitmap->bmWidthBytes = WIDTH_BYTES_ALIGN16(pBitmap->bmWidth, pBitmap->bmBitsPixel);
|
2009-01-09 02:06:39 +00:00
|
|
|
|
|
|
|
/* Check for DIB section */
|
2009-03-17 06:34:09 +00:00
|
|
|
if (psurf->hSecure)
|
|
|
|
{
|
|
|
|
/* Set bmBits in this case */
|
2009-01-09 02:06:39 +00:00
|
|
|
pBitmap->bmBits = psurf->SurfObj.pvBits;
|
2012-01-12 14:42:59 +00:00
|
|
|
/* DIBs data are 32 bits aligned */
|
|
|
|
pBitmap->bmWidthBytes = WIDTH_BYTES_ALIGN32(pBitmap->bmWidth, pBitmap->bmBitsPixel);
|
2009-01-09 02:06:39 +00:00
|
|
|
|
2009-03-17 06:34:09 +00:00
|
|
|
if (Count >= sizeof(DIBSECTION))
|
|
|
|
{
|
2009-01-09 02:06:39 +00:00
|
|
|
/* Fill rest of DIBSECTION */
|
|
|
|
PDIBSECTION pds = buffer;
|
|
|
|
|
2009-01-28 15:43:02 +00:00
|
|
|
pds->dsBmih.biSize = sizeof(BITMAPINFOHEADER);
|
2009-01-09 02:06:39 +00:00
|
|
|
pds->dsBmih.biWidth = pds->dsBm.bmWidth;
|
|
|
|
pds->dsBmih.biHeight = pds->dsBm.bmHeight;
|
|
|
|
pds->dsBmih.biPlanes = pds->dsBm.bmPlanes;
|
|
|
|
pds->dsBmih.biBitCount = pds->dsBm.bmBitsPixel;
|
2011-02-25 00:01:35 +00:00
|
|
|
|
|
|
|
switch (psurf->SurfObj.iBitmapFormat)
|
|
|
|
{
|
|
|
|
case BMF_1BPP:
|
|
|
|
case BMF_4BPP:
|
|
|
|
case BMF_8BPP:
|
|
|
|
pds->dsBmih.biCompression = BI_RGB;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BMF_16BPP:
|
|
|
|
if (psurf->ppal->flFlags & PAL_RGB16_555)
|
|
|
|
pds->dsBmih.biCompression = BI_RGB;
|
|
|
|
else
|
|
|
|
pds->dsBmih.biCompression = BI_BITFIELDS;
|
|
|
|
break;
|
|
|
|
|
2011-02-28 00:48:19 +00:00
|
|
|
case BMF_24BPP:
|
2011-02-25 00:01:35 +00:00
|
|
|
case BMF_32BPP:
|
2011-02-28 00:48:19 +00:00
|
|
|
/* 24/32bpp BI_RGB is actually BGR format */
|
|
|
|
if (psurf->ppal->flFlags & PAL_BGR)
|
2011-02-25 00:01:35 +00:00
|
|
|
pds->dsBmih.biCompression = BI_RGB;
|
|
|
|
else
|
|
|
|
pds->dsBmih.biCompression = BI_BITFIELDS;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case BMF_4RLE:
|
|
|
|
pds->dsBmih.biCompression = BI_RLE4;
|
|
|
|
break;
|
|
|
|
case BMF_8RLE:
|
|
|
|
pds->dsBmih.biCompression = BI_RLE8;
|
|
|
|
break;
|
|
|
|
case BMF_JPEG:
|
|
|
|
pds->dsBmih.biCompression = BI_JPEG;
|
|
|
|
break;
|
|
|
|
case BMF_PNG:
|
|
|
|
pds->dsBmih.biCompression = BI_PNG;
|
|
|
|
break;
|
|
|
|
default:
|
2011-12-14 04:07:06 +00:00
|
|
|
ASSERT(FALSE); /* This shouldn't happen */
|
2011-02-25 00:01:35 +00:00
|
|
|
}
|
|
|
|
|
2009-01-09 02:06:39 +00:00
|
|
|
pds->dsBmih.biSizeImage = psurf->SurfObj.cjBits;
|
|
|
|
pds->dsBmih.biXPelsPerMeter = 0;
|
|
|
|
pds->dsBmih.biYPelsPerMeter = 0;
|
2010-07-30 02:15:46 +00:00
|
|
|
pds->dsBmih.biClrUsed = psurf->ppal->NumColors;
|
2009-01-09 02:06:39 +00:00
|
|
|
pds->dsBmih.biClrImportant = psurf->biClrImportant;
|
2010-07-30 02:15:46 +00:00
|
|
|
pds->dsBitfields[0] = psurf->ppal->RedMask;
|
|
|
|
pds->dsBitfields[1] = psurf->ppal->GreenMask;
|
|
|
|
pds->dsBitfields[2] = psurf->ppal->BlueMask;
|
2009-01-09 02:06:39 +00:00
|
|
|
pds->dshSection = psurf->hDIBSection;
|
|
|
|
pds->dsOffset = psurf->dwOffset;
|
|
|
|
|
2009-03-17 06:34:09 +00:00
|
|
|
return sizeof(DIBSECTION);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2011-12-14 04:07:06 +00:00
|
|
|
/* Not set according to wine test, confirmed in win2k */
|
2009-03-17 06:34:09 +00:00
|
|
|
pBitmap->bmBits = NULL;
|
|
|
|
}
|
2009-01-09 02:06:39 +00:00
|
|
|
|
2009-03-17 06:34:09 +00:00
|
|
|
return sizeof(BITMAP);
|
1999-11-17 20:54:05 +00:00
|
|
|
}
|
2008-04-18 20:43:25 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
HDC
|
|
|
|
APIENTRY
|
|
|
|
NtGdiGetDCforBitmap(
|
|
|
|
IN HBITMAP hsurf)
|
|
|
|
{
|
2010-06-05 21:19:41 +00:00
|
|
|
HDC hdc = NULL;
|
2011-04-18 19:09:05 +00:00
|
|
|
PSURFACE psurf = SURFACE_ShareLockSurface(hsurf);
|
2009-03-17 06:34:09 +00:00
|
|
|
if (psurf)
|
|
|
|
{
|
2010-06-05 21:19:41 +00:00
|
|
|
hdc = psurf->hdc;
|
2011-04-18 19:09:05 +00:00
|
|
|
SURFACE_ShareUnlockSurface(psurf);
|
2009-03-17 06:34:09 +00:00
|
|
|
}
|
2010-06-05 21:19:41 +00:00
|
|
|
return hdc;
|
2008-04-18 20:43:25 +00:00
|
|
|
}
|
|
|
|
|
2010-08-02 00:53:25 +00:00
|
|
|
|
2003-05-18 17:16:18 +00:00
|
|
|
/* EOF */
|