mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 20:56:26 +00:00
[WIN32K]
- Move RLE specific code to it's own file (rlecomp.c) - Relace BitsPerFormat function with an array of UCHARs - Rewrite surface creation. Surfaces are now allocated from one central function SURFACE_AllocSurface, which sets the size, iType, iUniq, the handle and the default palette. - Implement SURFACE_vSetDefaultPalette, which sets the default RGB palette, based on bit depth. - Implement SURFACE_bSetBitmapBits, wich sets cjBits, pvBits, pvScan0 and lDelta and allocates memory if neccessary. - Use these functions for EngCreateBitmap, EngCreateDeviceBitmap, EngCreateDeviceSurface and IntCreateBitmap svn path=/branches/reactos-yarotows/; revision=47612
This commit is contained in:
parent
ca7f8096ff
commit
6068cac704
5 changed files with 454 additions and 594 deletions
140
subsystems/win32/win32k/eng/rlecomp.c
Normal file
140
subsystems/win32/win32k/eng/rlecomp.c
Normal file
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* PURPOSE: RLE compression
|
||||||
|
* FILE: subsystems/win32k/eng/rlecomp.c
|
||||||
|
* PROGRAMER: Jason Filby
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <win32k.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
enum Rle_EscapeCodes
|
||||||
|
{
|
||||||
|
RLE_EOL = 0, /* End of line */
|
||||||
|
RLE_END = 1, /* End of bitmap */
|
||||||
|
RLE_DELTA = 2 /* Delta */
|
||||||
|
};
|
||||||
|
|
||||||
|
VOID Decompress4bpp(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta)
|
||||||
|
{
|
||||||
|
int x = 0;
|
||||||
|
int y = Size.cy - 1;
|
||||||
|
int c;
|
||||||
|
int length;
|
||||||
|
int width = ((Size.cx+1)/2);
|
||||||
|
int height = Size.cy - 1;
|
||||||
|
BYTE *begin = CompressedBits;
|
||||||
|
BYTE *bits = CompressedBits;
|
||||||
|
BYTE *temp;
|
||||||
|
while (y >= 0)
|
||||||
|
{
|
||||||
|
length = *bits++ / 2;
|
||||||
|
if (length)
|
||||||
|
{
|
||||||
|
c = *bits++;
|
||||||
|
while (length--)
|
||||||
|
{
|
||||||
|
if (x >= width) break;
|
||||||
|
temp = UncompressedBits + (((height - y) * Delta) + x);
|
||||||
|
x++;
|
||||||
|
*temp = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length = *bits++;
|
||||||
|
switch (length)
|
||||||
|
{
|
||||||
|
case RLE_EOL:
|
||||||
|
x = 0;
|
||||||
|
y--;
|
||||||
|
break;
|
||||||
|
case RLE_END:
|
||||||
|
return;
|
||||||
|
case RLE_DELTA:
|
||||||
|
x += (*bits++)/2;
|
||||||
|
y -= (*bits++)/2;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
length /= 2;
|
||||||
|
while (length--)
|
||||||
|
{
|
||||||
|
c = *bits++;
|
||||||
|
if (x < width)
|
||||||
|
{
|
||||||
|
temp = UncompressedBits + (((height - y) * Delta) + x);
|
||||||
|
x++;
|
||||||
|
*temp = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((bits - begin) & 1)
|
||||||
|
{
|
||||||
|
bits++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID Decompress8bpp(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta)
|
||||||
|
{
|
||||||
|
int x = 0;
|
||||||
|
int y = Size.cy - 1;
|
||||||
|
int c;
|
||||||
|
int length;
|
||||||
|
int width = Size.cx;
|
||||||
|
int height = Size.cy - 1;
|
||||||
|
BYTE *begin = CompressedBits;
|
||||||
|
BYTE *bits = CompressedBits;
|
||||||
|
BYTE *temp;
|
||||||
|
while (y >= 0)
|
||||||
|
{
|
||||||
|
length = *bits++;
|
||||||
|
if (length)
|
||||||
|
{
|
||||||
|
c = *bits++;
|
||||||
|
while (length--)
|
||||||
|
{
|
||||||
|
if (x >= width) break;
|
||||||
|
temp = UncompressedBits + (((height - y) * Delta) + x);
|
||||||
|
x++;
|
||||||
|
*temp = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length = *bits++;
|
||||||
|
switch (length)
|
||||||
|
{
|
||||||
|
case RLE_EOL:
|
||||||
|
x = 0;
|
||||||
|
y--;
|
||||||
|
break;
|
||||||
|
case RLE_END:
|
||||||
|
return;
|
||||||
|
case RLE_DELTA:
|
||||||
|
x += *bits++;
|
||||||
|
y -= *bits++;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
while (length--)
|
||||||
|
{
|
||||||
|
c = *bits++;
|
||||||
|
if (x < width)
|
||||||
|
{
|
||||||
|
temp = UncompressedBits + (((height - y) * Delta) + x);
|
||||||
|
x++;
|
||||||
|
*temp = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((bits - begin) & 1)
|
||||||
|
{
|
||||||
|
bits++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,7 +3,8 @@
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
* PURPOSE: GDI Driver Surace Functions
|
* PURPOSE: GDI Driver Surace Functions
|
||||||
* FILE: subsys/win32k/eng/surface.c
|
* FILE: subsys/win32k/eng/surface.c
|
||||||
* PROGRAMER: Jason Filby
|
* PROGRAMERS: Jason Filby
|
||||||
|
* Timo Kreuzer
|
||||||
* REVISION HISTORY:
|
* REVISION HISTORY:
|
||||||
* 3/7/1999: Created
|
* 3/7/1999: Created
|
||||||
* 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED)
|
* 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED)
|
||||||
|
@ -17,43 +18,24 @@
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
enum Rle_EscapeCodes
|
ULONG giUniqueSurface = 0;
|
||||||
|
|
||||||
|
UCHAR
|
||||||
|
gajBitsPerFormat[11] =
|
||||||
{
|
{
|
||||||
RLE_EOL = 0, /* End of line */
|
0, /* 0: unused */
|
||||||
RLE_END = 1, /* End of bitmap */
|
1, /* 1: BMF_1BPP */
|
||||||
RLE_DELTA = 2 /* Delta */
|
4, /* 2: BMF_4BPP */
|
||||||
|
8, /* 3: BMF_8BPP */
|
||||||
|
16, /* 4: BMF_16BPP */
|
||||||
|
24, /* 5: BMF_24BPP */
|
||||||
|
32, /* 6: BMF_32BPP */
|
||||||
|
4, /* 7: BMF_4RLE */
|
||||||
|
8, /* 8: BMF_8RLE */
|
||||||
|
0, /* 9: BMF_JPEG */
|
||||||
|
0, /* 10: BMF_PNG */
|
||||||
};
|
};
|
||||||
|
|
||||||
INT FASTCALL BitsPerFormat(ULONG Format)
|
|
||||||
{
|
|
||||||
switch (Format)
|
|
||||||
{
|
|
||||||
case BMF_1BPP:
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
case BMF_4BPP:
|
|
||||||
/* Fall through */
|
|
||||||
case BMF_4RLE:
|
|
||||||
return 4;
|
|
||||||
|
|
||||||
case BMF_8BPP:
|
|
||||||
/* Fall through */
|
|
||||||
case BMF_8RLE:
|
|
||||||
return 8;
|
|
||||||
|
|
||||||
case BMF_16BPP:
|
|
||||||
return 16;
|
|
||||||
|
|
||||||
case BMF_24BPP:
|
|
||||||
return 24;
|
|
||||||
|
|
||||||
case BMF_32BPP:
|
|
||||||
return 32;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression)
|
ULONG FASTCALL BitmapFormat(WORD Bits, DWORD Compression)
|
||||||
{
|
{
|
||||||
|
@ -158,484 +140,189 @@ SURFACE_Cleanup(PVOID ObjectBody)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static
|
||||||
* @implemented
|
void
|
||||||
*/
|
SURFACE_vSetDefaultPalette(
|
||||||
HBITMAP APIENTRY
|
PSURFACE psurfBmp)
|
||||||
EngCreateDeviceBitmap(IN DHSURF dhsurf,
|
|
||||||
IN SIZEL Size,
|
|
||||||
IN ULONG Format)
|
|
||||||
{
|
{
|
||||||
HBITMAP NewBitmap;
|
ULONG cBitsPixel = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
|
||||||
SURFOBJ *pso;
|
|
||||||
|
|
||||||
NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
|
/* Find a suitable palette for this bitmap
|
||||||
if (!NewBitmap)
|
* Increment internal objects share count
|
||||||
|
* so we can call PALETTE_ShareUnlockPalette
|
||||||
|
* or GDIOBJ_IncrementShareCount safely */
|
||||||
|
switch(cBitsPixel)
|
||||||
{
|
{
|
||||||
DPRINT1("EngCreateBitmap failed\n");
|
case 1:
|
||||||
return 0;
|
psurfBmp->ppal = &gpalMono;
|
||||||
}
|
GDIOBJ_IncrementShareCount(&gpalMono.BaseObject);
|
||||||
|
|
||||||
pso = EngLockSurface((HSURF)NewBitmap);
|
|
||||||
if (!pso)
|
|
||||||
{
|
|
||||||
DPRINT1("EngLockSurface failed on newly created bitmap!\n");
|
|
||||||
GreDeleteObject(NewBitmap);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
pso->dhsurf = dhsurf;
|
|
||||||
pso->iType = STYPE_DEVBITMAP;
|
|
||||||
|
|
||||||
EngUnlockSurface(pso);
|
|
||||||
|
|
||||||
return NewBitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID Decompress4bpp(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta)
|
|
||||||
{
|
|
||||||
int x = 0;
|
|
||||||
int y = Size.cy - 1;
|
|
||||||
int c;
|
|
||||||
int length;
|
|
||||||
int width = ((Size.cx+1)/2);
|
|
||||||
int height = Size.cy - 1;
|
|
||||||
BYTE *begin = CompressedBits;
|
|
||||||
BYTE *bits = CompressedBits;
|
|
||||||
BYTE *temp;
|
|
||||||
while (y >= 0)
|
|
||||||
{
|
|
||||||
length = *bits++ / 2;
|
|
||||||
if (length)
|
|
||||||
{
|
|
||||||
c = *bits++;
|
|
||||||
while (length--)
|
|
||||||
{
|
|
||||||
if (x >= width) break;
|
|
||||||
temp = UncompressedBits + (((height - y) * Delta) + x);
|
|
||||||
x++;
|
|
||||||
*temp = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length = *bits++;
|
|
||||||
switch (length)
|
|
||||||
{
|
|
||||||
case RLE_EOL:
|
|
||||||
x = 0;
|
|
||||||
y--;
|
|
||||||
break;
|
break;
|
||||||
case RLE_END:
|
case 4:
|
||||||
return;
|
case 8:
|
||||||
case RLE_DELTA:
|
psurfBmp->ppal = PALETTE_ShareLockPalette(StockObjects[DEFAULT_PALETTE]);
|
||||||
x += (*bits++)/2;
|
break;
|
||||||
y -= (*bits++)/2;
|
case 15:
|
||||||
|
psurfBmp->ppal = &gpalRGB555;
|
||||||
|
GDIOBJ_IncrementShareCount(&gpalRGB555.BaseObject);
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
psurfBmp->ppal = &gpalRGB565;
|
||||||
|
GDIOBJ_IncrementShareCount(&gpalRGB565.BaseObject);
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
case 32:
|
||||||
|
psurfBmp->ppal = &gpalRGB;
|
||||||
|
GDIOBJ_IncrementShareCount((POBJ)&gpalRGB);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
length /= 2;
|
DPRINT1("Could not determine palette for bit depth %u.\n", cBitsPixel);
|
||||||
while (length--)
|
break;
|
||||||
{
|
|
||||||
c = *bits++;
|
|
||||||
if (x < width)
|
|
||||||
{
|
|
||||||
temp = UncompressedBits + (((height - y) * Delta) + x);
|
|
||||||
x++;
|
|
||||||
*temp = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((bits - begin) & 1)
|
|
||||||
{
|
|
||||||
bits++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID Decompress8bpp(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta)
|
PSURFACE
|
||||||
|
NTAPI
|
||||||
|
SURFACE_AllocSurface(
|
||||||
|
IN ULONG iType,
|
||||||
|
IN ULONG cx,
|
||||||
|
IN ULONG cy,
|
||||||
|
IN ULONG iFormat)
|
||||||
{
|
{
|
||||||
int x = 0;
|
|
||||||
int y = Size.cy - 1;
|
|
||||||
int c;
|
|
||||||
int length;
|
|
||||||
int width = Size.cx;
|
|
||||||
int height = Size.cy - 1;
|
|
||||||
BYTE *begin = CompressedBits;
|
|
||||||
BYTE *bits = CompressedBits;
|
|
||||||
BYTE *temp;
|
|
||||||
while (y >= 0)
|
|
||||||
{
|
|
||||||
length = *bits++;
|
|
||||||
if (length)
|
|
||||||
{
|
|
||||||
c = *bits++;
|
|
||||||
while (length--)
|
|
||||||
{
|
|
||||||
if (x >= width) break;
|
|
||||||
temp = UncompressedBits + (((height - y) * Delta) + x);
|
|
||||||
x++;
|
|
||||||
*temp = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length = *bits++;
|
|
||||||
switch (length)
|
|
||||||
{
|
|
||||||
case RLE_EOL:
|
|
||||||
x = 0;
|
|
||||||
y--;
|
|
||||||
break;
|
|
||||||
case RLE_END:
|
|
||||||
return;
|
|
||||||
case RLE_DELTA:
|
|
||||||
x += *bits++;
|
|
||||||
y -= *bits++;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
while (length--)
|
|
||||||
{
|
|
||||||
c = *bits++;
|
|
||||||
if (x < width)
|
|
||||||
{
|
|
||||||
temp = UncompressedBits + (((height - y) * Delta) + x);
|
|
||||||
x++;
|
|
||||||
*temp = c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((bits - begin) & 1)
|
|
||||||
{
|
|
||||||
bits++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HBITMAP FASTCALL
|
|
||||||
IntCreateBitmap(IN SIZEL Size,
|
|
||||||
IN LONG Width,
|
|
||||||
IN ULONG Format,
|
|
||||||
IN ULONG Flags,
|
|
||||||
IN PVOID Bits)
|
|
||||||
{
|
|
||||||
HBITMAP hbmp;
|
|
||||||
SURFOBJ *pso;
|
|
||||||
PSURFACE psurf;
|
PSURFACE psurf;
|
||||||
PVOID UncompressedBits;
|
SURFOBJ *pso;
|
||||||
ULONG UncompressedFormat;
|
|
||||||
|
|
||||||
if (Format == 0)
|
/* Allocate a SURFACE object */
|
||||||
return 0;
|
psurf = (PSURFACE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP);
|
||||||
|
|
||||||
psurf = SURFACE_AllocSurfaceWithHandle();
|
if (psurf)
|
||||||
if (psurf == NULL)
|
|
||||||
{
|
{
|
||||||
return 0;
|
/* Initialize the basic fields */
|
||||||
}
|
|
||||||
hbmp = psurf->BaseObject.hHmgr;
|
|
||||||
|
|
||||||
pso = &psurf->SurfObj;
|
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);
|
||||||
|
|
||||||
if (Format == BMF_4RLE)
|
SURFACE_vSetDefaultPalette(psurf);
|
||||||
{
|
|
||||||
pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_4BPP));
|
|
||||||
pso->cjBits = pso->lDelta * Size.cy;
|
|
||||||
UncompressedFormat = BMF_4BPP;
|
|
||||||
UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
|
|
||||||
Decompress4bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta);
|
|
||||||
Flags |= BMF_RLE_HACK;
|
|
||||||
}
|
|
||||||
else if (Format == BMF_8RLE)
|
|
||||||
{
|
|
||||||
pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_8BPP));
|
|
||||||
pso->cjBits = pso->lDelta * Size.cy;
|
|
||||||
UncompressedFormat = BMF_8BPP;
|
|
||||||
UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
|
|
||||||
Decompress8bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta);
|
|
||||||
Flags |= BMF_RLE_HACK;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pso->lDelta = abs(Width);
|
|
||||||
pso->cjBits = pso->lDelta * Size.cy;
|
|
||||||
UncompressedBits = Bits;
|
|
||||||
UncompressedFormat = Format;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UncompressedBits != NULL)
|
return psurf;
|
||||||
{
|
}
|
||||||
pso->pvBits = UncompressedBits;
|
|
||||||
Flags |= BMF_DONT_FREE;
|
BOOL
|
||||||
}
|
NTAPI
|
||||||
else
|
SURFACE_bSetBitmapBits(
|
||||||
{
|
IN PSURFACE psurf,
|
||||||
if (pso->cjBits == 0)
|
IN USHORT fjBitmap,
|
||||||
{
|
IN ULONG ulWidth,
|
||||||
pso->pvBits = NULL;
|
IN PVOID pvBits OPTIONAL)
|
||||||
}
|
{
|
||||||
else
|
SURFOBJ *pso = &psurf->SurfObj;
|
||||||
{
|
|
||||||
if (0 != (Flags & BMF_USERMEM))
|
|
||||||
{
|
|
||||||
pso->pvBits = EngAllocUserMem(pso->cjBits, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PVOID pvSection;
|
PVOID pvSection;
|
||||||
Flags |= BMF_KMSECTION;
|
|
||||||
pso->pvBits = EngAllocSectionMem(&pvSection,
|
/* Only bitmaps can have bits */
|
||||||
(Flags & BMF_NOZEROINIT) ?
|
ASSERT(psurf->SurfObj.iType == STYPE_BITMAP);
|
||||||
|
|
||||||
|
/* If no width is given, calculate it */
|
||||||
|
if (!ulWidth)
|
||||||
|
ulWidth = DIB_GetDIBWidthBytes(pso->sizlBitmap.cx,
|
||||||
|
BitsPerFormat(pso->iBitmapFormat));
|
||||||
|
|
||||||
|
/* Calculate the bitmap size in bytes */
|
||||||
|
pso->cjBits = ulWidth * pso->sizlBitmap.cy;
|
||||||
|
|
||||||
|
/* Did the caller provide bits? */
|
||||||
|
if (pvBits)
|
||||||
|
{
|
||||||
|
/* Yes, so let him free it */
|
||||||
|
fjBitmap |= BMF_DONT_FREE;
|
||||||
|
}
|
||||||
|
else if (pso->cjBits)
|
||||||
|
{
|
||||||
|
/* We must allocate memory, check what kind */
|
||||||
|
if (fjBitmap & BMF_USERMEM)
|
||||||
|
{
|
||||||
|
/* User mode memory was requested */
|
||||||
|
pvBits = EngAllocUserMem(pso->cjBits, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Use a kernel mode section */
|
||||||
|
fjBitmap |= BMF_KMSECTION;
|
||||||
|
pvBits = EngAllocSectionMem(&pvSection,
|
||||||
|
(fjBitmap & BMF_NOZEROINIT) ?
|
||||||
0 : FL_ZERO_MEMORY,
|
0 : FL_ZERO_MEMORY,
|
||||||
pso->cjBits, TAG_DIB);
|
pso->cjBits, TAG_DIB);
|
||||||
|
|
||||||
/* Free the section already, keep the mapping */
|
/* Free the section already, but keep the mapping */
|
||||||
EngFreeSectionMem(pvSection, NULL);
|
if (pvBits) EngFreeSectionMem(pvSection, NULL);
|
||||||
}
|
|
||||||
if (pso->pvBits == NULL)
|
|
||||||
{
|
|
||||||
SURFACE_UnlockSurface(psurf);
|
|
||||||
SURFACE_FreeSurfaceByHandle(hbmp);
|
|
||||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0 == (Flags & BMF_TOPDOWN))
|
/* Check for failure */
|
||||||
|
if (!pvBits) return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set pvBits, pvScan0 and lDelta */
|
||||||
|
pso->pvBits = pvBits;
|
||||||
|
if (fjBitmap & BMF_TOPDOWN)
|
||||||
{
|
{
|
||||||
pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - pso->lDelta);
|
/* Topdown is the normal way */
|
||||||
pso->lDelta = - pso->lDelta;
|
pso->pvScan0 = pso->pvBits;
|
||||||
|
pso->lDelta = ulWidth;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pso->pvScan0 = pso->pvBits;
|
/* Inversed bitmap (bottom up) */
|
||||||
|
pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ulWidth);
|
||||||
|
pso->lDelta = -ulWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
pso->dhsurf = 0; /* device managed surface */
|
pso->fjBitmap = fjBitmap;
|
||||||
pso->hsurf = (HSURF)hbmp;
|
|
||||||
pso->dhpdev = NULL;
|
|
||||||
pso->hdev = NULL;
|
|
||||||
pso->sizlBitmap = Size;
|
|
||||||
pso->iBitmapFormat = UncompressedFormat;
|
|
||||||
pso->iType = STYPE_BITMAP;
|
|
||||||
pso->fjBitmap = Flags & (BMF_TOPDOWN|BMF_NOZEROINIT|BMF_KMSECTION|BMF_USERMEM|BMF_DONT_FREE);
|
|
||||||
pso->iUniq = 0;
|
|
||||||
|
|
||||||
psurf->flags = 0;
|
/* Success */
|
||||||
psurf->sizlDim.cx = 0;
|
return TRUE;
|
||||||
psurf->sizlDim.cy = 0;
|
|
||||||
|
|
||||||
psurf->hSecure = NULL;
|
|
||||||
psurf->hDIBSection = NULL;
|
|
||||||
|
|
||||||
SURFACE_UnlockSurface(psurf);
|
|
||||||
|
|
||||||
return hbmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Name gleaned from C++ symbol information for SURFMEM::bInitDIB */
|
HBITMAP
|
||||||
typedef struct _DEVBITMAPINFO
|
APIENTRY
|
||||||
|
EngCreateBitmap(
|
||||||
|
IN SIZEL sizl,
|
||||||
|
IN LONG lWidth,
|
||||||
|
IN ULONG iFormat,
|
||||||
|
IN ULONG fl,
|
||||||
|
IN PVOID pvBits)
|
||||||
{
|
{
|
||||||
ULONG Format;
|
|
||||||
ULONG Width;
|
|
||||||
ULONG Height;
|
|
||||||
ULONG Flags;
|
|
||||||
ULONG Size;
|
|
||||||
} DEVBITMAPINFO, *PDEVBITMAPINFO;
|
|
||||||
|
|
||||||
SURFOBJ*
|
|
||||||
FASTCALL
|
|
||||||
SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
|
|
||||||
IN PVOID Bits)
|
|
||||||
{
|
|
||||||
BOOLEAN Compressed = FALSE;
|
|
||||||
ULONG ScanLine = 0; // Compiler is dumb
|
|
||||||
ULONG Size;
|
|
||||||
SURFOBJ *pso;
|
|
||||||
PSURFACE psurf;
|
PSURFACE psurf;
|
||||||
SIZEL LocalSize;
|
HBITMAP hbmp;
|
||||||
BOOLEAN AllocatedLocally = FALSE;
|
|
||||||
|
|
||||||
/*
|
/* Allocate a surface */
|
||||||
* First, check the format so we can get the aligned scanline width.
|
psurf = SURFACE_AllocSurface(STYPE_BITMAP, sizl.cx, sizl.cy, iFormat);
|
||||||
* RLE and the newer fancy-smanshy JPG/PNG support do NOT have scanlines
|
|
||||||
* since they are compressed surfaces!
|
|
||||||
*/
|
|
||||||
switch (BitmapInfo->Format)
|
|
||||||
{
|
|
||||||
case BMF_1BPP:
|
|
||||||
ScanLine = ((BitmapInfo->Width + 31) & ~31) >> 3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMF_4BPP:
|
|
||||||
ScanLine = ((BitmapInfo->Width + 7) & ~7) >> 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMF_8BPP:
|
|
||||||
ScanLine = (BitmapInfo->Width + 3) & ~3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMF_16BPP:
|
|
||||||
ScanLine = ((BitmapInfo->Width + 1) & ~1) << 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMF_24BPP:
|
|
||||||
ScanLine = ((BitmapInfo->Width * 3) + 3) & ~3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMF_32BPP:
|
|
||||||
ScanLine = BitmapInfo->Width << 2;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BMF_8RLE:
|
|
||||||
case BMF_4RLE:
|
|
||||||
case BMF_JPEG:
|
|
||||||
case BMF_PNG:
|
|
||||||
Compressed = TRUE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
DPRINT1("Invalid bitmap format\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Does the device manage its own surface? */
|
|
||||||
if (!Bits)
|
|
||||||
{
|
|
||||||
/* We need to allocate bits for the caller, figure out the size */
|
|
||||||
if (Compressed)
|
|
||||||
{
|
|
||||||
/* Note: we should not be seeing this scenario from ENGDDI */
|
|
||||||
ASSERT(FALSE);
|
|
||||||
Size = BitmapInfo->Size;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* The height times the bytes for each scanline */
|
|
||||||
Size = BitmapInfo->Height * ScanLine;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Size)
|
|
||||||
{
|
|
||||||
/* Check for allocation flag */
|
|
||||||
if (BitmapInfo->Flags & BMF_USERMEM)
|
|
||||||
{
|
|
||||||
/* Get the bits from user-mode memory */
|
|
||||||
Bits = EngAllocUserMem(Size, 'mbuG');
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PVOID pvSection;
|
|
||||||
BitmapInfo->Flags |= BMF_KMSECTION;
|
|
||||||
Bits = EngAllocSectionMem(&pvSection,
|
|
||||||
(BitmapInfo->Flags & BMF_NOZEROINIT) ?
|
|
||||||
0 : FL_ZERO_MEMORY,
|
|
||||||
Size, TAG_DIB);
|
|
||||||
|
|
||||||
/* Free the section already, keep the mapping */
|
|
||||||
EngFreeSectionMem(pvSection, NULL);
|
|
||||||
}
|
|
||||||
AllocatedLocally = TRUE;
|
|
||||||
/* Bail out if that failed */
|
|
||||||
if (!Bits) return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Should not have asked for user memory */
|
|
||||||
ASSERT((BitmapInfo->Flags & BMF_USERMEM) == 0);
|
|
||||||
|
|
||||||
/* Must not free anything */
|
|
||||||
BitmapInfo->Flags |= BMF_DONT_FREE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate the actual surface object structure */
|
|
||||||
psurf = SURFACE_AllocSurfaceWithHandle();
|
|
||||||
if (!psurf)
|
if (!psurf)
|
||||||
{
|
{
|
||||||
if(Bits && AllocatedLocally)
|
DPRINT1("SURFACE_AllocSurface failed.\n");
|
||||||
{
|
|
||||||
if(BitmapInfo->Flags & BMF_USERMEM)
|
|
||||||
EngFreeUserMem(Bits);
|
|
||||||
else
|
|
||||||
EngFreeMem(Bits);
|
|
||||||
}
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We should now have our surface object */
|
/* Get the handle for the bitmap */
|
||||||
pso = &psurf->SurfObj;
|
hbmp = (HBITMAP)psurf->SurfObj.hsurf;
|
||||||
|
|
||||||
/* Save format and flags */
|
/* Set the bitmap bits */
|
||||||
pso->iBitmapFormat = BitmapInfo->Format;
|
if (!SURFACE_bSetBitmapBits(psurf, fl, lWidth, pvBits))
|
||||||
pso->fjBitmap = BitmapInfo->Flags & (BMF_TOPDOWN | BMF_UMPDMEM | BMF_USERMEM | BMF_KMSECTION | BMF_DONT_FREE);
|
|
||||||
|
|
||||||
/* Save size and type */
|
|
||||||
LocalSize.cy = BitmapInfo->Height;
|
|
||||||
LocalSize.cx = BitmapInfo->Width;
|
|
||||||
pso->sizlBitmap = LocalSize;
|
|
||||||
pso->iType = STYPE_BITMAP;
|
|
||||||
|
|
||||||
/* Device-managed surface, no flags or dimension */
|
|
||||||
pso->dhsurf = 0;
|
|
||||||
pso->dhpdev = NULL;
|
|
||||||
pso->hdev = NULL;
|
|
||||||
psurf->flags = 0;
|
|
||||||
psurf->sizlDim.cx = 0;
|
|
||||||
psurf->sizlDim.cy = 0;
|
|
||||||
psurf->hSecure = NULL;
|
|
||||||
psurf->hDIBSection = NULL;
|
|
||||||
|
|
||||||
/* Set bits */
|
|
||||||
pso->pvBits = Bits;
|
|
||||||
|
|
||||||
/* Check for bitmap type */
|
|
||||||
if (!Compressed)
|
|
||||||
{
|
{
|
||||||
/* Number of bits is based on the height times the scanline */
|
/* Bail out if that failed */
|
||||||
pso->cjBits = BitmapInfo->Height * ScanLine;
|
DPRINT1("SURFACE_bSetBitmapBits failed.\n");
|
||||||
if (BitmapInfo->Flags & BMF_TOPDOWN)
|
SURFACE_FreeSurfaceByHandle(hbmp);
|
||||||
{
|
return NULL;
|
||||||
/* For topdown, the base address starts with the bits */
|
|
||||||
pso->pvScan0 = pso->pvBits;
|
|
||||||
pso->lDelta = ScanLine;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Otherwise we start with the end and go up */
|
|
||||||
pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ScanLine);
|
|
||||||
pso->lDelta = -ScanLine;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Compressed surfaces don't have scanlines! */
|
|
||||||
pso->lDelta = 0;
|
|
||||||
pso->cjBits = BitmapInfo->Size;
|
|
||||||
|
|
||||||
/* Check for JPG or PNG */
|
|
||||||
if ((BitmapInfo->Format != BMF_JPEG) && (BitmapInfo->Format != BMF_PNG))
|
|
||||||
{
|
|
||||||
/* Wherever the bit data is */
|
|
||||||
pso->pvScan0 = pso->pvBits;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Fancy formats don't use a base address */
|
|
||||||
pso->pvScan0 = NULL;
|
|
||||||
ASSERT(FALSE); // ENGDDI shouldn't be creating PNGs for drivers ;-)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Finally set the handle and uniq */
|
/* Set public ownership */
|
||||||
pso->hsurf = (HSURF)psurf->BaseObject.hHmgr;
|
GDIOBJ_SetOwnership(hbmp, NULL);
|
||||||
pso->iUniq = 0;
|
|
||||||
|
|
||||||
/* Unlock and return the surface */
|
/* Unlock the surface and return */
|
||||||
SURFACE_UnlockSurface(psurf);
|
SURFACE_UnlockSurface(psurf);
|
||||||
return pso;
|
return hbmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -643,103 +330,66 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
|
||||||
*/
|
*/
|
||||||
HBITMAP
|
HBITMAP
|
||||||
APIENTRY
|
APIENTRY
|
||||||
EngCreateBitmap(IN SIZEL Size,
|
EngCreateDeviceBitmap(
|
||||||
IN LONG Width,
|
IN DHSURF dhsurf,
|
||||||
IN ULONG Format,
|
IN SIZEL sizl,
|
||||||
IN ULONG Flags,
|
IN ULONG iFormat)
|
||||||
IN PVOID Bits)
|
|
||||||
{
|
{
|
||||||
SURFOBJ* Surface;
|
|
||||||
DEVBITMAPINFO BitmapInfo;
|
|
||||||
|
|
||||||
/* Capture the parameters */
|
|
||||||
BitmapInfo.Format = Format;
|
|
||||||
BitmapInfo.Width = Size.cx;
|
|
||||||
BitmapInfo.Height = Size.cy;
|
|
||||||
BitmapInfo.Flags = Flags;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If the display driver supports framebuffer access, use the scanline width
|
|
||||||
* to determine the actual width of the bitmap, and convert it to pels instead
|
|
||||||
* of bytes.
|
|
||||||
*/
|
|
||||||
if ((Bits) && (Width))
|
|
||||||
{
|
|
||||||
switch (BitmapInfo.Format)
|
|
||||||
{
|
|
||||||
/* Do the conversion for each bit depth we support */
|
|
||||||
case BMF_1BPP:
|
|
||||||
BitmapInfo.Width = Width * 8;
|
|
||||||
break;
|
|
||||||
case BMF_4BPP:
|
|
||||||
BitmapInfo.Width = Width * 2;
|
|
||||||
break;
|
|
||||||
case BMF_8BPP:
|
|
||||||
BitmapInfo.Width = Width;
|
|
||||||
break;
|
|
||||||
case BMF_16BPP:
|
|
||||||
BitmapInfo.Width = Width / 2;
|
|
||||||
break;
|
|
||||||
case BMF_24BPP:
|
|
||||||
BitmapInfo.Width = Width / 3;
|
|
||||||
break;
|
|
||||||
case BMF_32BPP:
|
|
||||||
BitmapInfo.Width = Width / 4;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now create the surface */
|
|
||||||
Surface = SURFMEM_bCreateDib(&BitmapInfo, Bits);
|
|
||||||
if (!Surface) return 0;
|
|
||||||
|
|
||||||
/* Set public ownership and reutrn the handle */
|
|
||||||
GDIOBJ_SetOwnership(Surface->hsurf, NULL);
|
|
||||||
return Surface->hsurf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @unimplemented
|
|
||||||
*/
|
|
||||||
HSURF APIENTRY
|
|
||||||
EngCreateDeviceSurface(IN DHSURF dhsurf,
|
|
||||||
IN SIZEL Size,
|
|
||||||
IN ULONG Format)
|
|
||||||
{
|
|
||||||
HSURF hsurf;
|
|
||||||
SURFOBJ *pso;
|
|
||||||
PSURFACE psurf;
|
PSURFACE psurf;
|
||||||
|
HBITMAP hbmp;
|
||||||
|
|
||||||
psurf = SURFACE_AllocSurfaceWithHandle();
|
/* Allocate a surface */
|
||||||
|
psurf = SURFACE_AllocSurface(STYPE_DEVBITMAP, sizl.cx, sizl.cy, iFormat);
|
||||||
if (!psurf)
|
if (!psurf)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
hsurf = psurf->BaseObject.hHmgr;
|
/* Set the device handle */
|
||||||
|
psurf->SurfObj.dhsurf = dhsurf;
|
||||||
|
|
||||||
|
/* Get the handle for the bitmap */
|
||||||
|
hbmp = (HBITMAP)psurf->SurfObj.hsurf;
|
||||||
|
|
||||||
|
/* Set public ownership */
|
||||||
|
GDIOBJ_SetOwnership(hbmp, NULL);
|
||||||
|
|
||||||
|
/* Unlock the surface and return */
|
||||||
|
SURFACE_UnlockSurface(psurf);
|
||||||
|
return hbmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
HSURF
|
||||||
|
APIENTRY
|
||||||
|
EngCreateDeviceSurface(
|
||||||
|
IN DHSURF dhsurf,
|
||||||
|
IN SIZEL sizl,
|
||||||
|
IN ULONG iFormat)
|
||||||
|
{
|
||||||
|
PSURFACE psurf;
|
||||||
|
HSURF hsurf;
|
||||||
|
|
||||||
|
/* Allocate a surface */
|
||||||
|
psurf = SURFACE_AllocSurface(STYPE_DEVICE, sizl.cx, sizl.cy, iFormat);
|
||||||
|
if (!psurf)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the device handle */
|
||||||
|
psurf->SurfObj.dhsurf = dhsurf;
|
||||||
|
|
||||||
|
/* Get the handle for the surface */
|
||||||
|
hsurf = psurf->SurfObj.hsurf;
|
||||||
|
|
||||||
|
/* Set public ownership */
|
||||||
GDIOBJ_SetOwnership(hsurf, NULL);
|
GDIOBJ_SetOwnership(hsurf, NULL);
|
||||||
|
|
||||||
pso = &psurf->SurfObj;
|
/* Unlock the surface and return */
|
||||||
|
|
||||||
pso->dhsurf = dhsurf;
|
|
||||||
pso->hsurf = hsurf;
|
|
||||||
pso->sizlBitmap = Size;
|
|
||||||
pso->iBitmapFormat = Format;
|
|
||||||
pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format));
|
|
||||||
pso->iType = STYPE_DEVICE;
|
|
||||||
pso->iUniq = 0;
|
|
||||||
pso->pvBits = NULL;
|
|
||||||
|
|
||||||
psurf->flags = 0;
|
|
||||||
|
|
||||||
SURFACE_UnlockSurface(psurf);
|
SURFACE_UnlockSurface(psurf);
|
||||||
|
|
||||||
return hsurf;
|
return hsurf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
BOOL
|
BOOL
|
||||||
APIENTRY
|
APIENTRY
|
||||||
EngAssociateSurface(
|
EngAssociateSurface(
|
||||||
|
@ -777,10 +427,8 @@ EngAssociateSurface(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
BOOL
|
||||||
* @implemented
|
APIENTRY
|
||||||
*/
|
|
||||||
BOOL APIENTRY
|
|
||||||
EngModifySurface(
|
EngModifySurface(
|
||||||
IN HSURF hsurf,
|
IN HSURF hsurf,
|
||||||
IN HDEV hdev,
|
IN HDEV hdev,
|
||||||
|
@ -823,10 +471,9 @@ EngModifySurface(
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @implemented
|
BOOL
|
||||||
*/
|
APIENTRY
|
||||||
BOOL APIENTRY
|
|
||||||
EngDeleteSurface(IN HSURF hsurf)
|
EngDeleteSurface(IN HSURF hsurf)
|
||||||
{
|
{
|
||||||
GDIOBJ_SetOwnership(hsurf, PsGetCurrentProcess());
|
GDIOBJ_SetOwnership(hsurf, PsGetCurrentProcess());
|
||||||
|
@ -834,17 +481,16 @@ EngDeleteSurface(IN HSURF hsurf)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
BOOL
|
||||||
* @implemented
|
APIENTRY
|
||||||
*/
|
EngEraseSurface(
|
||||||
BOOL APIENTRY
|
SURFOBJ *pso,
|
||||||
EngEraseSurface(SURFOBJ *pso,
|
RECTL *prcl,
|
||||||
RECTL *Rect,
|
|
||||||
ULONG iColor)
|
ULONG iColor)
|
||||||
{
|
{
|
||||||
ASSERT(pso);
|
ASSERT(pso);
|
||||||
ASSERT(Rect);
|
ASSERT(prcl);
|
||||||
return FillSolid(pso, Rect, iColor);
|
return FillSolid(pso, prcl, iColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -857,10 +503,8 @@ NtGdiEngLockSurface(IN HSURF hsurf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
SURFOBJ *
|
||||||
* @implemented
|
APIENTRY
|
||||||
*/
|
|
||||||
SURFOBJ * APIENTRY
|
|
||||||
EngLockSurface(IN HSURF hsurf)
|
EngLockSurface(IN HSURF hsurf)
|
||||||
{
|
{
|
||||||
SURFACE *psurf = GDIOBJ_ShareLockObj(hsurf, GDI_OBJECT_TYPE_BITMAP);
|
SURFACE *psurf = GDIOBJ_ShareLockObj(hsurf, GDI_OBJECT_TYPE_BITMAP);
|
||||||
|
@ -871,20 +515,15 @@ EngLockSurface(IN HSURF hsurf)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
/*
|
APIENTRY
|
||||||
* @implemented
|
|
||||||
*/
|
|
||||||
VOID APIENTRY
|
|
||||||
NtGdiEngUnlockSurface(IN SURFOBJ *pso)
|
NtGdiEngUnlockSurface(IN SURFOBJ *pso)
|
||||||
{
|
{
|
||||||
EngUnlockSurface(pso);
|
EngUnlockSurface(pso);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
VOID
|
||||||
* @implemented
|
APIENTRY
|
||||||
*/
|
|
||||||
VOID APIENTRY
|
|
||||||
EngUnlockSurface(IN SURFOBJ *pso)
|
EngUnlockSurface(IN SURFOBJ *pso)
|
||||||
{
|
{
|
||||||
if (pso != NULL)
|
if (pso != NULL)
|
||||||
|
@ -894,5 +533,74 @@ EngUnlockSurface(IN SURFOBJ *pso)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HBITMAP
|
||||||
|
FASTCALL
|
||||||
|
IntCreateBitmap(
|
||||||
|
IN SIZEL Size,
|
||||||
|
IN LONG Width,
|
||||||
|
IN ULONG Format,
|
||||||
|
IN ULONG Flags,
|
||||||
|
IN PVOID Bits)
|
||||||
|
{
|
||||||
|
HBITMAP hbmp;
|
||||||
|
SURFOBJ *pso;
|
||||||
|
PSURFACE psurf;
|
||||||
|
PVOID UncompressedBits;
|
||||||
|
ULONG UncompressedFormat;
|
||||||
|
|
||||||
|
if (Format == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Allocate a surface */
|
||||||
|
psurf = SURFACE_AllocSurface(STYPE_BITMAP, Size.cx, Size.cy, Format);
|
||||||
|
if (!psurf)
|
||||||
|
{
|
||||||
|
DPRINT1("SURFACE_AllocSurface failed.\n");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the handle for the bitmap and the surfobj */
|
||||||
|
hbmp = (HBITMAP)psurf->SurfObj.hsurf;
|
||||||
|
pso = &psurf->SurfObj;
|
||||||
|
|
||||||
|
if (Format == BMF_4RLE)
|
||||||
|
{
|
||||||
|
pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_4BPP));
|
||||||
|
pso->cjBits = pso->lDelta * Size.cy;
|
||||||
|
UncompressedFormat = BMF_4BPP;
|
||||||
|
UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
|
||||||
|
Decompress4bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta);
|
||||||
|
Flags |= BMF_RLE_HACK;
|
||||||
|
}
|
||||||
|
else if (Format == BMF_8RLE)
|
||||||
|
{
|
||||||
|
pso->lDelta = DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(BMF_8BPP));
|
||||||
|
pso->cjBits = pso->lDelta * Size.cy;
|
||||||
|
UncompressedFormat = BMF_8BPP;
|
||||||
|
UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
|
||||||
|
Decompress8bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta);
|
||||||
|
Flags |= BMF_RLE_HACK;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pso->lDelta = abs(Width);
|
||||||
|
pso->cjBits = pso->lDelta * Size.cy;
|
||||||
|
UncompressedBits = Bits;
|
||||||
|
UncompressedFormat = Format;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the bitmap bits */
|
||||||
|
if (!SURFACE_bSetBitmapBits(psurf, Flags, Width, UncompressedBits))
|
||||||
|
{
|
||||||
|
/* Bail out if that failed */
|
||||||
|
DPRINT1("SURFACE_bSetBitmapBits failed.\n");
|
||||||
|
SURFACE_FreeSurfaceByHandle(hbmp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Unlock the surface and return */
|
||||||
|
SURFACE_UnlockSurface(psurf);
|
||||||
|
return hbmp;
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -36,3 +36,6 @@ EngAllocSectionMem(
|
||||||
IN SIZE_T cjSize,
|
IN SIZE_T cjSize,
|
||||||
IN ULONG ulTag);
|
IN ULONG ulTag);
|
||||||
|
|
||||||
|
VOID Decompress4bpp(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta);
|
||||||
|
VOID Decompress8bpp(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta);
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,6 @@ typedef struct _SURFACE
|
||||||
|
|
||||||
/* Internal interface */
|
/* Internal interface */
|
||||||
|
|
||||||
#define SURFACE_AllocSurface() ((PSURFACE) GDIOBJ_AllocObj(GDIObjType_SURF_TYPE))
|
|
||||||
#define SURFACE_AllocSurfaceWithHandle() ((PSURFACE) GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP))
|
#define SURFACE_AllocSurfaceWithHandle() ((PSURFACE) GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP))
|
||||||
#define SURFACE_FreeSurface(pBMObj) GDIOBJ_FreeObj((POBJ) pBMObj, GDIObjType_SURF_TYPE)
|
#define SURFACE_FreeSurface(pBMObj) GDIOBJ_FreeObj((POBJ) pBMObj, GDIObjType_SURF_TYPE)
|
||||||
#define SURFACE_FreeSurfaceByHandle(hBMObj) GDIOBJ_FreeObjByHandle((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_BITMAP)
|
#define SURFACE_FreeSurfaceByHandle(hBMObj) GDIOBJ_FreeObjByHandle((HGDIOBJ) hBMObj, GDI_OBJECT_TYPE_BITMAP)
|
||||||
|
@ -109,8 +108,17 @@ typedef struct _SURFACE
|
||||||
|
|
||||||
BOOL INTERNAL_CALL SURFACE_Cleanup(PVOID ObjectBody);
|
BOOL INTERNAL_CALL SURFACE_Cleanup(PVOID ObjectBody);
|
||||||
|
|
||||||
|
PSURFACE
|
||||||
|
NTAPI
|
||||||
|
SURFACE_AllocSurface(
|
||||||
|
IN ULONG iType,
|
||||||
|
IN ULONG cx,
|
||||||
|
IN ULONG cy,
|
||||||
|
IN ULONG iFormat);
|
||||||
|
|
||||||
#define GDIDEV(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))
|
#define GDIDEV(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))
|
||||||
#define GDIDEVFUNCS(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))->DriverFunctions
|
#define GDIDEVFUNCS(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))->DriverFunctions
|
||||||
|
|
||||||
INT FASTCALL BitsPerFormat (ULONG Format);
|
|
||||||
ULONG FASTCALL BitmapFormat (WORD Bits, DWORD Compression);
|
ULONG FASTCALL BitmapFormat (WORD Bits, DWORD Compression);
|
||||||
|
extern UCHAR gajBitsPerFormat[];
|
||||||
|
#define BitsPerFormat(Format) gajBitsPerFormat[Format]
|
||||||
|
|
|
@ -78,6 +78,7 @@
|
||||||
<file>paint.c</file>
|
<file>paint.c</file>
|
||||||
<file>pdevobj.c</file>
|
<file>pdevobj.c</file>
|
||||||
<file>perfcnt.c</file>
|
<file>perfcnt.c</file>
|
||||||
|
<file>rlecomp.c</file>
|
||||||
<file>semaphor.c</file>
|
<file>semaphor.c</file>
|
||||||
<file>sort.c</file>
|
<file>sort.c</file>
|
||||||
<file>string.c</file>
|
<file>string.c</file>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue