mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 13:56:05 +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
|
||||
* PURPOSE: GDI Driver Surace Functions
|
||||
* FILE: subsys/win32k/eng/surface.c
|
||||
* PROGRAMER: Jason Filby
|
||||
* PROGRAMERS: Jason Filby
|
||||
* Timo Kreuzer
|
||||
* REVISION HISTORY:
|
||||
* 3/7/1999: Created
|
||||
* 9/11/2000: Updated to handle real pixel packed bitmaps (UPDATE TO DATE COMPLETED)
|
||||
|
@ -17,43 +18,24 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
enum Rle_EscapeCodes
|
||||
ULONG giUniqueSurface = 0;
|
||||
|
||||
UCHAR
|
||||
gajBitsPerFormat[11] =
|
||||
{
|
||||
RLE_EOL = 0, /* End of line */
|
||||
RLE_END = 1, /* End of bitmap */
|
||||
RLE_DELTA = 2 /* Delta */
|
||||
0, /* 0: unused */
|
||||
1, /* 1: BMF_1BPP */
|
||||
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)
|
||||
{
|
||||
|
@ -158,484 +140,189 @@ SURFACE_Cleanup(PVOID ObjectBody)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
HBITMAP APIENTRY
|
||||
EngCreateDeviceBitmap(IN DHSURF dhsurf,
|
||||
IN SIZEL Size,
|
||||
IN ULONG Format)
|
||||
static
|
||||
void
|
||||
SURFACE_vSetDefaultPalette(
|
||||
PSURFACE psurfBmp)
|
||||
{
|
||||
HBITMAP NewBitmap;
|
||||
SURFOBJ *pso;
|
||||
ULONG cBitsPixel = BitsPerFormat(psurfBmp->SurfObj.iBitmapFormat);
|
||||
|
||||
NewBitmap = EngCreateBitmap(Size, DIB_GetDIBWidthBytes(Size.cx, BitsPerFormat(Format)), Format, 0, NULL);
|
||||
if (!NewBitmap)
|
||||
/* Find a suitable palette for this bitmap
|
||||
* Increment internal objects share count
|
||||
* so we can call PALETTE_ShareUnlockPalette
|
||||
* or GDIOBJ_IncrementShareCount safely */
|
||||
switch(cBitsPixel)
|
||||
{
|
||||
DPRINT1("EngCreateBitmap failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
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--;
|
||||
case 1:
|
||||
psurfBmp->ppal = &gpalMono;
|
||||
GDIOBJ_IncrementShareCount(&gpalMono.BaseObject);
|
||||
break;
|
||||
case RLE_END:
|
||||
return;
|
||||
case RLE_DELTA:
|
||||
x += (*bits++)/2;
|
||||
y -= (*bits++)/2;
|
||||
case 4:
|
||||
case 8:
|
||||
psurfBmp->ppal = PALETTE_ShareLockPalette(StockObjects[DEFAULT_PALETTE]);
|
||||
break;
|
||||
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;
|
||||
default:
|
||||
length /= 2;
|
||||
while (length--)
|
||||
{
|
||||
c = *bits++;
|
||||
if (x < width)
|
||||
{
|
||||
temp = UncompressedBits + (((height - y) * Delta) + x);
|
||||
x++;
|
||||
*temp = c;
|
||||
}
|
||||
}
|
||||
if ((bits - begin) & 1)
|
||||
{
|
||||
bits++;
|
||||
}
|
||||
}
|
||||
}
|
||||
DPRINT1("Could not determine palette for bit depth %u.\n", cBitsPixel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
PVOID UncompressedBits;
|
||||
ULONG UncompressedFormat;
|
||||
SURFOBJ *pso;
|
||||
|
||||
if (Format == 0)
|
||||
return 0;
|
||||
/* Allocate a SURFACE object */
|
||||
psurf = (PSURFACE)GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP);
|
||||
|
||||
psurf = SURFACE_AllocSurfaceWithHandle();
|
||||
if (psurf == NULL)
|
||||
if (psurf)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
hbmp = psurf->BaseObject.hHmgr;
|
||||
|
||||
/* 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);
|
||||
|
||||
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;
|
||||
SURFACE_vSetDefaultPalette(psurf);
|
||||
}
|
||||
|
||||
if (UncompressedBits != NULL)
|
||||
{
|
||||
pso->pvBits = UncompressedBits;
|
||||
Flags |= BMF_DONT_FREE;
|
||||
return psurf;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pso->cjBits == 0)
|
||||
{
|
||||
pso->pvBits = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 != (Flags & BMF_USERMEM))
|
||||
{
|
||||
pso->pvBits = EngAllocUserMem(pso->cjBits, 0);
|
||||
}
|
||||
else
|
||||
|
||||
BOOL
|
||||
NTAPI
|
||||
SURFACE_bSetBitmapBits(
|
||||
IN PSURFACE psurf,
|
||||
IN USHORT fjBitmap,
|
||||
IN ULONG ulWidth,
|
||||
IN PVOID pvBits OPTIONAL)
|
||||
{
|
||||
SURFOBJ *pso = &psurf->SurfObj;
|
||||
PVOID pvSection;
|
||||
Flags |= BMF_KMSECTION;
|
||||
pso->pvBits = EngAllocSectionMem(&pvSection,
|
||||
(Flags & BMF_NOZEROINIT) ?
|
||||
|
||||
/* Only bitmaps can have bits */
|
||||
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,
|
||||
pso->cjBits, TAG_DIB);
|
||||
|
||||
/* Free the section already, keep the mapping */
|
||||
EngFreeSectionMem(pvSection, NULL);
|
||||
}
|
||||
if (pso->pvBits == NULL)
|
||||
{
|
||||
SURFACE_UnlockSurface(psurf);
|
||||
SURFACE_FreeSurfaceByHandle(hbmp);
|
||||
SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/* Free the section already, but keep the mapping */
|
||||
if (pvBits) EngFreeSectionMem(pvSection, NULL);
|
||||
}
|
||||
|
||||
if (0 == (Flags & BMF_TOPDOWN))
|
||||
{
|
||||
pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - pso->lDelta);
|
||||
pso->lDelta = - pso->lDelta;
|
||||
/* Check for failure */
|
||||
if (!pvBits) return FALSE;
|
||||
}
|
||||
else
|
||||
|
||||
/* Set pvBits, pvScan0 and lDelta */
|
||||
pso->pvBits = pvBits;
|
||||
if (fjBitmap & BMF_TOPDOWN)
|
||||
{
|
||||
/* Topdown is the normal way */
|
||||
pso->pvScan0 = pso->pvBits;
|
||||
pso->lDelta = ulWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Inversed bitmap (bottom up) */
|
||||
pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ulWidth);
|
||||
pso->lDelta = -ulWidth;
|
||||
}
|
||||
|
||||
pso->dhsurf = 0; /* device managed surface */
|
||||
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;
|
||||
pso->fjBitmap = fjBitmap;
|
||||
|
||||
psurf->flags = 0;
|
||||
psurf->sizlDim.cx = 0;
|
||||
psurf->sizlDim.cy = 0;
|
||||
|
||||
psurf->hSecure = NULL;
|
||||
psurf->hDIBSection = NULL;
|
||||
|
||||
SURFACE_UnlockSurface(psurf);
|
||||
|
||||
return hbmp;
|
||||
/* Success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Name gleaned from C++ symbol information for SURFMEM::bInitDIB */
|
||||
typedef struct _DEVBITMAPINFO
|
||||
HBITMAP
|
||||
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;
|
||||
SIZEL LocalSize;
|
||||
BOOLEAN AllocatedLocally = FALSE;
|
||||
HBITMAP hbmp;
|
||||
|
||||
/*
|
||||
* First, check the format so we can get the aligned scanline width.
|
||||
* 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();
|
||||
/* Allocate a surface */
|
||||
psurf = SURFACE_AllocSurface(STYPE_BITMAP, sizl.cx, sizl.cy, iFormat);
|
||||
if (!psurf)
|
||||
{
|
||||
if(Bits && AllocatedLocally)
|
||||
{
|
||||
if(BitmapInfo->Flags & BMF_USERMEM)
|
||||
EngFreeUserMem(Bits);
|
||||
else
|
||||
EngFreeMem(Bits);
|
||||
}
|
||||
DPRINT1("SURFACE_AllocSurface failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* We should now have our surface object */
|
||||
pso = &psurf->SurfObj;
|
||||
/* Get the handle for the bitmap */
|
||||
hbmp = (HBITMAP)psurf->SurfObj.hsurf;
|
||||
|
||||
/* Save format and flags */
|
||||
pso->iBitmapFormat = BitmapInfo->Format;
|
||||
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)
|
||||
/* Set the bitmap bits */
|
||||
if (!SURFACE_bSetBitmapBits(psurf, fl, lWidth, pvBits))
|
||||
{
|
||||
/* Number of bits is based on the height times the scanline */
|
||||
pso->cjBits = BitmapInfo->Height * ScanLine;
|
||||
if (BitmapInfo->Flags & BMF_TOPDOWN)
|
||||
{
|
||||
/* 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 ;-)
|
||||
}
|
||||
/* Bail out if that failed */
|
||||
DPRINT1("SURFACE_bSetBitmapBits failed.\n");
|
||||
SURFACE_FreeSurfaceByHandle(hbmp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Finally set the handle and uniq */
|
||||
pso->hsurf = (HSURF)psurf->BaseObject.hHmgr;
|
||||
pso->iUniq = 0;
|
||||
/* Set public ownership */
|
||||
GDIOBJ_SetOwnership(hbmp, NULL);
|
||||
|
||||
/* Unlock and return the surface */
|
||||
/* Unlock the surface and return */
|
||||
SURFACE_UnlockSurface(psurf);
|
||||
return pso;
|
||||
return hbmp;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -643,103 +330,66 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
|
|||
*/
|
||||
HBITMAP
|
||||
APIENTRY
|
||||
EngCreateBitmap(IN SIZEL Size,
|
||||
IN LONG Width,
|
||||
IN ULONG Format,
|
||||
IN ULONG Flags,
|
||||
IN PVOID Bits)
|
||||
EngCreateDeviceBitmap(
|
||||
IN DHSURF dhsurf,
|
||||
IN SIZEL sizl,
|
||||
IN ULONG iFormat)
|
||||
{
|
||||
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;
|
||||
HBITMAP hbmp;
|
||||
|
||||
psurf = SURFACE_AllocSurfaceWithHandle();
|
||||
/* Allocate a surface */
|
||||
psurf = SURFACE_AllocSurface(STYPE_DEVBITMAP, sizl.cx, sizl.cy, iFormat);
|
||||
if (!psurf)
|
||||
{
|
||||
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);
|
||||
|
||||
pso = &psurf->SurfObj;
|
||||
|
||||
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;
|
||||
|
||||
/* Unlock the surface and return */
|
||||
SURFACE_UnlockSurface(psurf);
|
||||
|
||||
return hsurf;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL
|
||||
APIENTRY
|
||||
EngAssociateSurface(
|
||||
|
@ -777,10 +427,8 @@ EngAssociateSurface(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL APIENTRY
|
||||
BOOL
|
||||
APIENTRY
|
||||
EngModifySurface(
|
||||
IN HSURF hsurf,
|
||||
IN HDEV hdev,
|
||||
|
@ -823,10 +471,9 @@ EngModifySurface(
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL APIENTRY
|
||||
|
||||
BOOL
|
||||
APIENTRY
|
||||
EngDeleteSurface(IN HSURF hsurf)
|
||||
{
|
||||
GDIOBJ_SetOwnership(hsurf, PsGetCurrentProcess());
|
||||
|
@ -834,17 +481,16 @@ EngDeleteSurface(IN HSURF hsurf)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
BOOL APIENTRY
|
||||
EngEraseSurface(SURFOBJ *pso,
|
||||
RECTL *Rect,
|
||||
BOOL
|
||||
APIENTRY
|
||||
EngEraseSurface(
|
||||
SURFOBJ *pso,
|
||||
RECTL *prcl,
|
||||
ULONG iColor)
|
||||
{
|
||||
ASSERT(pso);
|
||||
ASSERT(Rect);
|
||||
return FillSolid(pso, Rect, iColor);
|
||||
ASSERT(prcl);
|
||||
return FillSolid(pso, prcl, iColor);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -857,10 +503,8 @@ NtGdiEngLockSurface(IN HSURF hsurf)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
SURFOBJ * APIENTRY
|
||||
SURFOBJ *
|
||||
APIENTRY
|
||||
EngLockSurface(IN HSURF hsurf)
|
||||
{
|
||||
SURFACE *psurf = GDIOBJ_ShareLockObj(hsurf, GDI_OBJECT_TYPE_BITMAP);
|
||||
|
@ -871,20 +515,15 @@ EngLockSurface(IN HSURF hsurf)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID APIENTRY
|
||||
VOID
|
||||
APIENTRY
|
||||
NtGdiEngUnlockSurface(IN SURFOBJ *pso)
|
||||
{
|
||||
EngUnlockSurface(pso);
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
VOID APIENTRY
|
||||
VOID
|
||||
APIENTRY
|
||||
EngUnlockSurface(IN SURFOBJ *pso)
|
||||
{
|
||||
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 */
|
||||
|
|
|
@ -36,3 +36,6 @@ EngAllocSectionMem(
|
|||
IN SIZE_T cjSize,
|
||||
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 */
|
||||
|
||||
#define SURFACE_AllocSurface() ((PSURFACE) GDIOBJ_AllocObj(GDIObjType_SURF_TYPE))
|
||||
#define SURFACE_AllocSurfaceWithHandle() ((PSURFACE) GDIOBJ_AllocObjWithHandle(GDI_OBJECT_TYPE_BITMAP))
|
||||
#define SURFACE_FreeSurface(pBMObj) GDIOBJ_FreeObj((POBJ) pBMObj, GDIObjType_SURF_TYPE)
|
||||
#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);
|
||||
|
||||
PSURFACE
|
||||
NTAPI
|
||||
SURFACE_AllocSurface(
|
||||
IN ULONG iType,
|
||||
IN ULONG cx,
|
||||
IN ULONG cy,
|
||||
IN ULONG iFormat);
|
||||
|
||||
#define GDIDEV(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))
|
||||
#define GDIDEVFUNCS(SurfObj) ((PDEVOBJ *)((SurfObj)->hdev))->DriverFunctions
|
||||
|
||||
INT FASTCALL BitsPerFormat (ULONG Format);
|
||||
ULONG FASTCALL BitmapFormat (WORD Bits, DWORD Compression);
|
||||
extern UCHAR gajBitsPerFormat[];
|
||||
#define BitsPerFormat(Format) gajBitsPerFormat[Format]
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
<file>paint.c</file>
|
||||
<file>pdevobj.c</file>
|
||||
<file>perfcnt.c</file>
|
||||
<file>rlecomp.c</file>
|
||||
<file>semaphor.c</file>
|
||||
<file>sort.c</file>
|
||||
<file>string.c</file>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue