mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 22:02:14 +00:00
[WIN32K]
Rewrite SURFACE_AllocSurface(), which now does the part of the former SURFACE_bSetBitmapBits() as well. This is to allocate the bits for a bitmap directly with the SURFACE object in one allocation. Also don't use kernel mode sections anymore by default, but paged pool memory. svn path=/trunk/; revision=56460
This commit is contained in:
parent
2ba64e0951
commit
46c9a27251
4 changed files with 260 additions and 190 deletions
|
@ -15,7 +15,7 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
ULONG giUniqueSurface = 0;
|
||||
LONG giUniqueSurface = 0;
|
||||
|
||||
UCHAR
|
||||
gajBitsPerFormat[11] =
|
||||
|
@ -34,7 +34,9 @@ gajBitsPerFormat[11] =
|
|||
};
|
||||
|
||||
|
||||
ULONG FASTCALL BitmapFormat(ULONG cBits, ULONG iCompression)
|
||||
ULONG
|
||||
FASTCALL
|
||||
BitmapFormat(ULONG cBits, ULONG iCompression)
|
||||
{
|
||||
switch (iCompression)
|
||||
{
|
||||
|
@ -107,15 +109,10 @@ SURFACE_Cleanup(PVOID ObjectBody)
|
|||
ASSERT(FALSE);
|
||||
}
|
||||
}
|
||||
else if (psurf->SurfObj.fjBitmap & BMF_RLE_HACK)
|
||||
else if (psurf->SurfObj.fjBitmap & BMF_POOLALLOC)
|
||||
{
|
||||
/* HACK: Free RLE decompressed bits */
|
||||
EngFreeMem(pvBits);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There should be nothing to free */
|
||||
ASSERT(psurf->SurfObj.fjBitmap & BMF_DONT_FREE);
|
||||
/* Free a pool allocation */
|
||||
ExFreePool(pvBits);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,126 +129,162 @@ SURFACE_Cleanup(PVOID ObjectBody)
|
|||
PSURFACE
|
||||
NTAPI
|
||||
SURFACE_AllocSurface(
|
||||
IN USHORT iType,
|
||||
IN ULONG cx,
|
||||
IN ULONG cy,
|
||||
IN ULONG iFormat)
|
||||
_In_ USHORT iType,
|
||||
_In_ ULONG cx,
|
||||
_In_ ULONG cy,
|
||||
_In_ ULONG iFormat,
|
||||
_In_ ULONG fjBitmap,
|
||||
_In_opt_ ULONG cjWidth,
|
||||
_In_opt_ PVOID pvBits)
|
||||
{
|
||||
ULONG cBitsPixel, cjBits, cjObject;
|
||||
PSURFACE psurf;
|
||||
SURFOBJ *pso;
|
||||
PVOID pvSection;
|
||||
|
||||
ASSERT(!pvBits || (iType == STYPE_BITMAP));
|
||||
ASSERT(pvBits || !(fjBitmap & BMF_DONT_FREE));
|
||||
ASSERT(!pvBits || !(fjBitmap & BMF_SINGLEALLOC));
|
||||
|
||||
/* Verify format */
|
||||
if (iFormat < BMF_1BPP || iFormat > BMF_PNG)
|
||||
if ((iFormat < BMF_1BPP) || (iFormat > BMF_PNG))
|
||||
{
|
||||
DPRINT1("Invalid bitmap format: %ld\n", iFormat);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate a SURFACE object */
|
||||
psurf = (PSURFACE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP, sizeof(SURFACE));
|
||||
|
||||
if (psurf)
|
||||
{
|
||||
/* Initialize the basic fields */
|
||||
pso = &psurf->SurfObj;
|
||||
pso->hsurf = psurf->BaseObject.hHmgr;
|
||||
pso->sizlBitmap.cx = cx;
|
||||
pso->sizlBitmap.cy = cy;
|
||||
pso->iBitmapFormat = iFormat;
|
||||
pso->iType = iType;
|
||||
pso->iUniq = InterlockedIncrement((PLONG)&giUniqueSurface);
|
||||
|
||||
/* Assign a default palette and increment its reference count */
|
||||
psurf->ppal = appalSurfaceDefault[iFormat];
|
||||
GDIOBJ_vReferenceObjectByPointer(&psurf->ppal->BaseObject);
|
||||
}
|
||||
|
||||
return psurf;
|
||||
}
|
||||
|
||||
BOOL
|
||||
NTAPI
|
||||
SURFACE_bSetBitmapBits(
|
||||
IN PSURFACE psurf,
|
||||
IN ULONG fjBitmap,
|
||||
IN ULONG ulWidth,
|
||||
IN PVOID pvBits OPTIONAL)
|
||||
{
|
||||
SURFOBJ *pso = &psurf->SurfObj;
|
||||
PVOID pvSection;
|
||||
UCHAR cBitsPixel;
|
||||
|
||||
/* Only bitmaps can have bits */
|
||||
ASSERT(psurf->SurfObj.iType == STYPE_BITMAP);
|
||||
|
||||
/* Get bits per pixel from the format */
|
||||
cBitsPixel = gajBitsPerFormat[pso->iBitmapFormat];
|
||||
cBitsPixel = gajBitsPerFormat[iFormat];
|
||||
|
||||
/* Is a width in bytes given? */
|
||||
if (ulWidth)
|
||||
/* Are bits and a width in bytes given? */
|
||||
if (pvBits && cjWidth)
|
||||
{
|
||||
/* Align the width (Windows compatibility, drivers expect that) */
|
||||
ulWidth = WIDTH_BYTES_ALIGN32((ulWidth << 3) / cBitsPixel, cBitsPixel);
|
||||
cjWidth = WIDTH_BYTES_ALIGN32((cjWidth << 3) / cBitsPixel, cBitsPixel);
|
||||
}
|
||||
else
|
||||
{
|
||||
else
|
||||
{
|
||||
/* Calculate width from the bitmap width in pixels */
|
||||
ulWidth = WIDTH_BYTES_ALIGN32(pso->sizlBitmap.cx, cBitsPixel);
|
||||
}
|
||||
cjWidth = WIDTH_BYTES_ALIGN32(cx, cBitsPixel);
|
||||
}
|
||||
|
||||
/* Calculate the bitmap size in bytes */
|
||||
pso->cjBits = ulWidth * pso->sizlBitmap.cy;
|
||||
cjBits = cjWidth * cy;
|
||||
|
||||
/* Did the caller provide bits? */
|
||||
if (pvBits)
|
||||
/* Check if we need an extra large object */
|
||||
if ((iType == STYPE_BITMAP) && (pvBits == NULL) &&
|
||||
!(fjBitmap & BMF_USERMEM) && !(fjBitmap & BMF_KMSECTION))
|
||||
{
|
||||
/* Yes, so let him free it */
|
||||
fjBitmap |= BMF_DONT_FREE;
|
||||
/* Allocate an object large enough to hold the bits */
|
||||
cjObject = sizeof(SURFACE) + cjBits;
|
||||
}
|
||||
else if (pso->cjBits)
|
||||
else
|
||||
{
|
||||
/* We must allocate memory, check what kind */
|
||||
if (fjBitmap & BMF_USERMEM)
|
||||
/* Otherwise just allocate the SURFACE structure */
|
||||
cjObject = sizeof(SURFACE);
|
||||
}
|
||||
|
||||
/* Check for arithmetic overflow */
|
||||
if ((cjBits < cjWidth) || (cjObject < sizeof(SURFACE)))
|
||||
{
|
||||
/* Fail! */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate a SURFACE object */
|
||||
psurf = (PSURFACE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP, cjObject);
|
||||
if (!psurf)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize the basic fields */
|
||||
pso = &psurf->SurfObj;
|
||||
pso->hsurf = psurf->BaseObject.hHmgr;
|
||||
pso->sizlBitmap.cx = cx;
|
||||
pso->sizlBitmap.cy = cy;
|
||||
pso->iBitmapFormat = iFormat;
|
||||
pso->iType = iType;
|
||||
pso->fjBitmap = (USHORT)fjBitmap;
|
||||
pso->iUniq = InterlockedIncrement(&giUniqueSurface);
|
||||
pso->cjBits = cjBits;
|
||||
|
||||
/* Check if we need a bitmap buffer */
|
||||
if (iType == STYPE_BITMAP)
|
||||
{
|
||||
/* Check if we got one or if we need to allocate one */
|
||||
if (pvBits != NULL)
|
||||
{
|
||||
/* Use the caller provided buffer */
|
||||
pso->pvBits = pvBits;
|
||||
}
|
||||
else if (fjBitmap & BMF_USERMEM)
|
||||
{
|
||||
/* User mode memory was requested */
|
||||
pvBits = EngAllocUserMem(pso->cjBits, 0);
|
||||
pso->pvBits = EngAllocUserMem(cjBits, 0);
|
||||
|
||||
/* Check for failure */
|
||||
if (!pso->pvBits)
|
||||
{
|
||||
GDIOBJ_vDeleteObject(&psurf->BaseObject);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else if (fjBitmap & BMF_KMSECTION)
|
||||
{
|
||||
/* Use a kernel mode section */
|
||||
pso->pvBits = EngAllocSectionMem(&pvSection,
|
||||
(fjBitmap & BMF_NOZEROINIT) ?
|
||||
0 : FL_ZERO_MEMORY,
|
||||
cjBits, TAG_DIB);
|
||||
|
||||
/* Check for failure */
|
||||
if (!pso->pvBits)
|
||||
{
|
||||
GDIOBJ_vDeleteObject(&psurf->BaseObject);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Free the section already, but keep the mapping */
|
||||
EngFreeSectionMem(pvSection, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Use a kernel mode section */
|
||||
fjBitmap |= BMF_KMSECTION;
|
||||
pvBits = EngAllocSectionMem(&pvSection,
|
||||
(fjBitmap & BMF_NOZEROINIT) ?
|
||||
0 : FL_ZERO_MEMORY,
|
||||
pso->cjBits, TAG_DIB);
|
||||
/* Buffer is after the object */
|
||||
pso->pvBits = psurf + 1;
|
||||
|
||||
/* Free the section already, but keep the mapping */
|
||||
if (pvBits) EngFreeSectionMem(pvSection, NULL);
|
||||
/* Zero the buffer, except requested otherwise */
|
||||
if (!(fjBitmap & BMF_NOZEROINIT))
|
||||
{
|
||||
RtlZeroMemory(pso->pvBits, cjBits);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for failure */
|
||||
if (!pvBits) return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There are no bitmap bits */
|
||||
pso->pvBits = NULL;
|
||||
}
|
||||
|
||||
/* Set pvBits, pvScan0 and lDelta */
|
||||
pso->pvBits = pvBits;
|
||||
/* Set pvScan0 and lDelta */
|
||||
if (fjBitmap & BMF_TOPDOWN)
|
||||
{
|
||||
/* Topdown is the normal way */
|
||||
pso->pvScan0 = pso->pvBits;
|
||||
pso->lDelta = ulWidth;
|
||||
pso->lDelta = cjWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Inversed bitmap (bottom up) */
|
||||
pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ulWidth);
|
||||
pso->lDelta = -(LONG)ulWidth;
|
||||
pso->pvScan0 = ((PCHAR)pso->pvBits + pso->cjBits - cjWidth);
|
||||
pso->lDelta = -(LONG)cjWidth;
|
||||
}
|
||||
|
||||
pso->fjBitmap = (USHORT)fjBitmap;
|
||||
/* Assign a default palette and increment its reference count */
|
||||
psurf->ppal = appalSurfaceDefault[iFormat];
|
||||
GDIOBJ_vReferenceObjectByPointer(&psurf->ppal->BaseObject);
|
||||
|
||||
/* Success */
|
||||
return TRUE;
|
||||
return psurf;
|
||||
}
|
||||
|
||||
HBITMAP
|
||||
|
@ -267,7 +300,13 @@ EngCreateBitmap(
|
|||
HBITMAP hbmp;
|
||||
|
||||
/* Allocate a surface */
|
||||
psurf = SURFACE_AllocSurface(STYPE_BITMAP, sizl.cx, sizl.cy, iFormat);
|
||||
psurf = SURFACE_AllocSurface(STYPE_BITMAP,
|
||||
sizl.cx,
|
||||
sizl.cy,
|
||||
iFormat,
|
||||
fl,
|
||||
lWidth,
|
||||
pvBits);
|
||||
if (!psurf)
|
||||
{
|
||||
DPRINT1("SURFACE_AllocSurface failed.\n");
|
||||
|
@ -277,15 +316,6 @@ EngCreateBitmap(
|
|||
/* Get the handle for the bitmap */
|
||||
hbmp = (HBITMAP)psurf->SurfObj.hsurf;
|
||||
|
||||
/* Set the bitmap bits */
|
||||
if (!SURFACE_bSetBitmapBits(psurf, fl, lWidth, pvBits))
|
||||
{
|
||||
/* Bail out if that failed */
|
||||
DPRINT1("SURFACE_bSetBitmapBits failed.\n");
|
||||
GDIOBJ_vDeleteObject(&psurf->BaseObject);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set public ownership */
|
||||
GDIOBJ_vSetObjectOwner(&psurf->BaseObject, GDI_OBJ_HMGR_PUBLIC);
|
||||
|
||||
|
@ -308,10 +338,17 @@ EngCreateDeviceBitmap(
|
|||
HBITMAP hbmp;
|
||||
|
||||
/* Allocate a surface */
|
||||
psurf = SURFACE_AllocSurface(STYPE_DEVBITMAP, sizl.cx, sizl.cy, iFormat);
|
||||
psurf = SURFACE_AllocSurface(STYPE_DEVBITMAP,
|
||||
sizl.cx,
|
||||
sizl.cy,
|
||||
iFormat,
|
||||
0,
|
||||
0,
|
||||
NULL);
|
||||
if (!psurf)
|
||||
{
|
||||
return 0;
|
||||
DPRINT1("SURFACE_AllocSurface failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set the device handle */
|
||||
|
@ -339,10 +376,17 @@ EngCreateDeviceSurface(
|
|||
HSURF hsurf;
|
||||
|
||||
/* Allocate a surface */
|
||||
psurf = SURFACE_AllocSurface(STYPE_DEVICE, sizl.cx, sizl.cy, iFormat);
|
||||
psurf = SURFACE_AllocSurface(STYPE_DEVICE,
|
||||
sizl.cx,
|
||||
sizl.cy,
|
||||
iFormat,
|
||||
0,
|
||||
0,
|
||||
NULL);
|
||||
if (!psurf)
|
||||
{
|
||||
return 0;
|
||||
DPRINT1("SURFACE_AllocSurface failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set the device handle */
|
||||
|
|
|
@ -83,7 +83,8 @@ typedef struct _SURFACE
|
|||
|
||||
#define BMF_DONT_FREE 0x100
|
||||
#define BMF_RLE_HACK 0x200
|
||||
|
||||
#define BMF_SINGLEALLOC 0x400
|
||||
#define BMF_POOLALLOC 0x800
|
||||
|
||||
/* Internal interface */
|
||||
|
||||
|
@ -99,31 +100,30 @@ typedef struct _SURFACE
|
|||
#define SURFACE_ShareUnlockSurface(pBMObj) \
|
||||
GDIOBJ_vDereferenceObject ((POBJ)pBMObj)
|
||||
|
||||
BOOL NTAPI SURFACE_Cleanup(PVOID ObjectBody);
|
||||
|
||||
PSURFACE
|
||||
NTAPI
|
||||
SURFACE_AllocSurface(
|
||||
IN USHORT iType,
|
||||
IN ULONG cx,
|
||||
IN ULONG cy,
|
||||
IN ULONG iFormat);
|
||||
|
||||
BOOL
|
||||
NTAPI
|
||||
SURFACE_bSetBitmapBits(
|
||||
IN PSURFACE psurf,
|
||||
IN ULONG fjBitmap,
|
||||
IN ULONG ulWidth,
|
||||
IN PVOID pvBits OPTIONAL);
|
||||
|
||||
#define GDIDEV(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))
|
||||
#define GDIDEVFUNCS(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))->DriverFunctions
|
||||
|
||||
ULONG FASTCALL BitmapFormat(ULONG cBits, ULONG iCompression);
|
||||
extern UCHAR gajBitsPerFormat[];
|
||||
#define BitsPerFormat(Format) gajBitsPerFormat[Format]
|
||||
|
||||
#define WIDTH_BYTES_ALIGN32(cx, bpp) ((((cx) * (bpp) + 31) & ~31) >> 3)
|
||||
#define WIDTH_BYTES_ALIGN16(cx, bpp) ((((cx) * (bpp) + 15) & ~15) >> 3)
|
||||
|
||||
ULONG
|
||||
FASTCALL
|
||||
BitmapFormat(ULONG cBits, ULONG iCompression);
|
||||
|
||||
BOOL
|
||||
NTAPI
|
||||
SURFACE_Cleanup(PVOID ObjectBody);
|
||||
|
||||
PSURFACE
|
||||
NTAPI
|
||||
SURFACE_AllocSurface(
|
||||
_In_ USHORT iType,
|
||||
_In_ ULONG cx,
|
||||
_In_ ULONG cy,
|
||||
_In_ ULONG iFormat,
|
||||
_In_ ULONG fjBitmap,
|
||||
_In_opt_ ULONG cjWidth,
|
||||
_In_opt_ PVOID pvBits);
|
||||
|
|
|
@ -1160,34 +1160,36 @@ NtGdiGetPixel(
|
|||
}
|
||||
|
||||
/* Allocate a surface */
|
||||
psurfDest = SURFACE_AllocSurface(STYPE_BITMAP, 1, 1, BMF_32BPP);
|
||||
psurfDest = SURFACE_AllocSurface(STYPE_BITMAP,
|
||||
1,
|
||||
1,
|
||||
BMF_32BPP,
|
||||
BMF_DONT_FREE,
|
||||
0,
|
||||
&ulRGBColor);
|
||||
if (psurfDest)
|
||||
{
|
||||
/* Set the bitmap bits */
|
||||
if (SURFACE_bSetBitmapBits(psurfDest, 0, 0, &ulRGBColor))
|
||||
{
|
||||
RECTL rclDest = {0, 0, 1, 1};
|
||||
EXLATEOBJ exlo;
|
||||
RECTL rclDest = {0, 0, 1, 1};
|
||||
EXLATEOBJ exlo;
|
||||
|
||||
/* Translate from the source palette to RGB color */
|
||||
EXLATEOBJ_vInitialize(&exlo,
|
||||
psurfSrc->ppal,
|
||||
&gpalRGB,
|
||||
0,
|
||||
RGB(0xff,0xff,0xff),
|
||||
RGB(0,0,0));
|
||||
/* Translate from the source palette to RGB color */
|
||||
EXLATEOBJ_vInitialize(&exlo,
|
||||
psurfSrc->ppal,
|
||||
&gpalRGB,
|
||||
0,
|
||||
RGB(0xff,0xff,0xff),
|
||||
RGB(0,0,0));
|
||||
|
||||
/* Call the copy bits function */
|
||||
EngCopyBits(&psurfDest->SurfObj,
|
||||
&psurfSrc->SurfObj,
|
||||
NULL,
|
||||
&exlo.xlo,
|
||||
&rclDest,
|
||||
&ptlSrc);
|
||||
/* Call the copy bits function */
|
||||
EngCopyBits(&psurfDest->SurfObj,
|
||||
&psurfSrc->SurfObj,
|
||||
NULL,
|
||||
&exlo.xlo,
|
||||
&rclDest,
|
||||
&ptlSrc);
|
||||
|
||||
/* Cleanup the XLATEOBJ */
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
}
|
||||
/* Cleanup the XLATEOBJ */
|
||||
EXLATEOBJ_vCleanup(&exlo);
|
||||
|
||||
/* Delete the surface */
|
||||
GDIOBJ_vDeleteObject(&psurfDest->BaseObject);
|
||||
|
|
|
@ -56,25 +56,36 @@ GreCreateBitmapEx(
|
|||
{
|
||||
PSURFACE psurf;
|
||||
HBITMAP hbmp;
|
||||
PVOID pvCompressedBits;
|
||||
|
||||
/* Verify format */
|
||||
if (iFormat < BMF_1BPP || iFormat > BMF_PNG) return NULL;
|
||||
|
||||
/* The infamous RLE hack */
|
||||
if ((iFormat == BMF_4RLE) || (iFormat == BMF_8RLE))
|
||||
{
|
||||
pvCompressedBits = pvBits;
|
||||
pvBits = NULL;
|
||||
iFormat = (iFormat == BMF_4RLE) ? BMF_4BPP : BMF_8BPP;
|
||||
}
|
||||
|
||||
/* Allocate a surface */
|
||||
psurf = SURFACE_AllocSurface(STYPE_BITMAP, nWidth, nHeight, iFormat);
|
||||
psurf = SURFACE_AllocSurface(STYPE_BITMAP,
|
||||
nWidth,
|
||||
nHeight,
|
||||
iFormat,
|
||||
fjBitmap,
|
||||
cjWidthBytes,
|
||||
pvBits);
|
||||
if (!psurf)
|
||||
{
|
||||
DPRINT1("SURFACE_AllocSurface failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get the handle for the bitmap */
|
||||
hbmp = (HBITMAP)psurf->SurfObj.hsurf;
|
||||
|
||||
/* The infamous RLE hack */
|
||||
if (iFormat == BMF_4RLE || iFormat == BMF_8RLE)
|
||||
if ((iFormat == BMF_4RLE) || (iFormat == BMF_8RLE))
|
||||
{
|
||||
PVOID pvCompressedBits;
|
||||
SIZEL sizl;
|
||||
LONG lDelta;
|
||||
|
||||
|
@ -82,34 +93,17 @@ GreCreateBitmapEx(
|
|||
sizl.cy = nHeight;
|
||||
lDelta = WIDTH_BYTES_ALIGN32(nWidth, gajBitsPerFormat[iFormat]);
|
||||
|
||||
pvCompressedBits = pvBits;
|
||||
pvBits = EngAllocMem(FL_ZERO_MEMORY, lDelta * nHeight, TAG_DIB);
|
||||
if (!pvBits)
|
||||
{
|
||||
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
GDIOBJ_vDeleteObject(&psurf->BaseObject);
|
||||
return NULL;
|
||||
}
|
||||
pvBits = psurf->SurfObj.pvBits;
|
||||
DecompressBitmap(sizl, pvCompressedBits, pvBits, lDelta, iFormat);
|
||||
fjBitmap |= BMF_RLE_HACK;
|
||||
|
||||
iFormat = iFormat == BMF_4RLE ? BMF_4BPP : BMF_8BPP;
|
||||
psurf->SurfObj.iBitmapFormat = iFormat;
|
||||
psurf->SurfObj.fjBitmap |= BMF_RLE_HACK;
|
||||
}
|
||||
|
||||
/* Get the handle for the bitmap */
|
||||
hbmp = (HBITMAP)psurf->SurfObj.hsurf;
|
||||
|
||||
/* Mark as API bitmap */
|
||||
psurf->flags |= (flags | API_BITMAP);
|
||||
|
||||
/* Set the bitmap bits */
|
||||
if (!SURFACE_bSetBitmapBits(psurf, fjBitmap, cjWidthBytes, pvBits))
|
||||
{
|
||||
/* Bail out if that failed */
|
||||
DPRINT1("SURFACE_bSetBitmapBits failed.\n");
|
||||
EngSetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
GDIOBJ_vDeleteObject(&psurf->BaseObject);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Unlock the surface and return */
|
||||
SURFACE_UnlockSurface(psurf);
|
||||
return hbmp;
|
||||
|
@ -149,8 +143,9 @@ NtGdiCreateBitmap(
|
|||
IN OPTIONAL LPBYTE pUnsafeBits)
|
||||
{
|
||||
HBITMAP hbmp;
|
||||
ULONG cRealBpp, cjWidthBytes, iFormat;
|
||||
ULONG cRealBpp, cjWidthBytes, iFormat, fjBitmap;
|
||||
ULONGLONG cjSize;
|
||||
PSURFACE psurf;
|
||||
|
||||
/* Calculate bitmap format and real bits per pixel. */
|
||||
iFormat = BitmapFormat(cBitsPixel * cPlanes, BI_RGB);
|
||||
|
@ -170,12 +165,27 @@ NtGdiCreateBitmap(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Call internal function. */
|
||||
hbmp = GreCreateBitmapEx(nWidth, nHeight, 0, iFormat, 0, 0, NULL, DDB_SURFACE);
|
||||
|
||||
if (pUnsafeBits && hbmp)
|
||||
/* Allocate the surface (but don't set the bits) */
|
||||
psurf = SURFACE_AllocSurface(STYPE_BITMAP,
|
||||
nWidth,
|
||||
nHeight,
|
||||
iFormat,
|
||||
fjBitmap,
|
||||
0,
|
||||
NULL);
|
||||
if (!psurf)
|
||||
{
|
||||
PSURFACE psurf = SURFACE_ShareLockSurface(hbmp);
|
||||
DPRINT1("SURFACE_AllocSurface failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Mark as API and DDB bitmap */
|
||||
psurf->flags |= (API_BITMAP | DDB_SURFACE);
|
||||
|
||||
/* Check if we have bits to set */
|
||||
if (pUnsafeBits)
|
||||
{
|
||||
/* Protect with SEH and copy the bits */
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForRead(pUnsafeBits, (SIZE_T)cjSize, 1);
|
||||
|
@ -187,9 +197,18 @@ NtGdiCreateBitmap(
|
|||
_SEH2_YIELD(return NULL;)
|
||||
}
|
||||
_SEH2_END
|
||||
|
||||
SURFACE_ShareUnlockSurface(psurf);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Zero the bits */
|
||||
RtlZeroMemory(psurf->SurfObj.pvBits, psurf->SurfObj.cjBits);
|
||||
}
|
||||
|
||||
/* Get the handle for the bitmap */
|
||||
hbmp = (HBITMAP)psurf->SurfObj.hsurf;
|
||||
|
||||
/* Unlock the surface */
|
||||
SURFACE_UnlockSurface(psurf);
|
||||
|
||||
return hbmp;
|
||||
}
|
||||
|
@ -324,7 +343,8 @@ NtGdiCreateCompatibleBitmap(
|
|||
HBITMAP Bmp;
|
||||
PDC Dc;
|
||||
|
||||
if (Width <= 0 || Height <= 0 || (Width * Height) > 0x3FFFFFFF)
|
||||
/* Check parameters */
|
||||
if ((Width <= 0) || (Height <= 0) || ((Width * Height) > 0x3FFFFFFF))
|
||||
{
|
||||
EngSetLastError(ERROR_INVALID_PARAMETER);
|
||||
return NULL;
|
||||
|
@ -351,17 +371,19 @@ NtGdiCreateCompatibleBitmap(
|
|||
return Bmp;
|
||||
}
|
||||
|
||||
BOOL APIENTRY
|
||||
BOOL
|
||||
APIENTRY
|
||||
NtGdiGetBitmapDimension(
|
||||
HBITMAP hBitmap,
|
||||
LPSIZE Dimension)
|
||||
LPSIZE psizDim)
|
||||
{
|
||||
PSURFACE psurfBmp;
|
||||
BOOL Ret = TRUE;
|
||||
BOOL bResult = TRUE;
|
||||
|
||||
if (hBitmap == NULL)
|
||||
return FALSE;
|
||||
|
||||
/* Lock the bitmap */
|
||||
psurfBmp = SURFACE_ShareLockSurface(hBitmap);
|
||||
if (psurfBmp == NULL)
|
||||
{
|
||||
|
@ -369,20 +391,22 @@ NtGdiGetBitmapDimension(
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* Use SEH to copy the data to the caller */
|
||||
_SEH2_TRY
|
||||
{
|
||||
ProbeForWrite(Dimension, sizeof(SIZE), 1);
|
||||
*Dimension = psurfBmp->sizlDim;
|
||||
ProbeForWrite(psizDim, sizeof(SIZE), 1);
|
||||
*psizDim = psurfBmp->sizlDim;
|
||||
}
|
||||
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
Ret = FALSE;
|
||||
bResult = FALSE;
|
||||
}
|
||||
_SEH2_END
|
||||
|
||||
/* Unlock the bitmap */
|
||||
SURFACE_ShareUnlockSurface(psurfBmp);
|
||||
|
||||
return Ret;
|
||||
return bResult;
|
||||
}
|
||||
|
||||
|
||||
|
@ -580,7 +604,7 @@ BITMAP_CopyBitmap(HBITMAP hBitmap)
|
|||
psurfSrc->SurfObj.sizlBitmap.cy,
|
||||
abs(psurfSrc->SurfObj.lDelta),
|
||||
psurfSrc->SurfObj.iBitmapFormat,
|
||||
psurfSrc->SurfObj.fjBitmap,
|
||||
psurfSrc->SurfObj.fjBitmap & BMF_TOPDOWN,
|
||||
psurfSrc->SurfObj.cjBits,
|
||||
NULL,
|
||||
psurfSrc->flags);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue