mirror of
https://github.com/reactos/reactos.git
synced 2025-08-09 14:42:52 +00:00
[WIN32K]
- Bring back support for RLE compressed bitmaps. - Merge the decompress functions for 4bb and 8bpp bitmaps to one generic function. - Simplify SURFMEM_bCreateDib a bit by not allowing PNG/JPEG compression at all. See issue #5276 for more details. svn path=/trunk/; revision=47134
This commit is contained in:
parent
bfe6479cf7
commit
006a12e270
1 changed files with 99 additions and 129 deletions
|
@ -204,81 +204,31 @@ EngCreateDeviceBitmap(IN DHSURF dhsurf,
|
||||||
return NewBitmap;
|
return NewBitmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID Decompress4bpp(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta)
|
BOOL DecompressBitmap(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LONG Delta, ULONG Format)
|
||||||
{
|
{
|
||||||
int x = 0;
|
INT x = 0;
|
||||||
int y = Size.cy - 1;
|
INT y = Size.cy - 1;
|
||||||
int c;
|
INT c;
|
||||||
int length;
|
INT length;
|
||||||
int width = ((Size.cx+1)/2);
|
INT width;
|
||||||
int height = Size.cy - 1;
|
INT height = Size.cy - 1;
|
||||||
BYTE *begin = CompressedBits;
|
BYTE *begin = CompressedBits;
|
||||||
BYTE *bits = CompressedBits;
|
BYTE *bits = CompressedBits;
|
||||||
BYTE *temp;
|
BYTE *temp;
|
||||||
while (y >= 0)
|
INT shift = 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)
|
if (Format == BMF_4RLE)
|
||||||
{
|
shift = 1;
|
||||||
int x = 0;
|
else if(Format != BMF_8RLE)
|
||||||
int y = Size.cy - 1;
|
return FALSE;
|
||||||
int c;
|
|
||||||
int length;
|
width = ((Size.cx + shift) >> shift);
|
||||||
int width = Size.cx;
|
|
||||||
int height = Size.cy - 1;
|
_SEH2_TRY
|
||||||
BYTE *begin = CompressedBits;
|
{
|
||||||
BYTE *bits = CompressedBits;
|
|
||||||
BYTE *temp;
|
|
||||||
while (y >= 0)
|
while (y >= 0)
|
||||||
{
|
{
|
||||||
length = *bits++;
|
length = (*bits++) >> shift;
|
||||||
if (length)
|
if (length)
|
||||||
{
|
{
|
||||||
c = *bits++;
|
c = *bits++;
|
||||||
|
@ -300,12 +250,13 @@ VOID Decompress8bpp(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LO
|
||||||
y--;
|
y--;
|
||||||
break;
|
break;
|
||||||
case RLE_END:
|
case RLE_END:
|
||||||
return;
|
_SEH2_YIELD(return TRUE);
|
||||||
case RLE_DELTA:
|
case RLE_DELTA:
|
||||||
x += *bits++;
|
x += (*bits++) >> shift;
|
||||||
y -= *bits++;
|
y -= (*bits++) >> shift;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
length = length >> shift;
|
||||||
while (length--)
|
while (length--)
|
||||||
{
|
{
|
||||||
c = *bits++;
|
c = *bits++;
|
||||||
|
@ -323,6 +274,15 @@ VOID Decompress8bpp(SIZEL Size, BYTE *CompressedBits, BYTE *UncompressedBits, LO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
||||||
|
{
|
||||||
|
DPRINT1("Decoding error\n");
|
||||||
|
_SEH2_YIELD(return FALSE);
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HBITMAP FASTCALL
|
HBITMAP FASTCALL
|
||||||
|
@ -362,7 +322,7 @@ IntCreateBitmap(IN SIZEL Size,
|
||||||
pso->cjBits = pso->lDelta * Size.cy;
|
pso->cjBits = pso->lDelta * Size.cy;
|
||||||
UncompressedFormat = BMF_4BPP;
|
UncompressedFormat = BMF_4BPP;
|
||||||
UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
|
UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
|
||||||
Decompress4bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta);
|
DecompressBitmap(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta, Format);
|
||||||
}
|
}
|
||||||
else if (Format == BMF_8RLE)
|
else if (Format == BMF_8RLE)
|
||||||
{
|
{
|
||||||
|
@ -370,7 +330,7 @@ IntCreateBitmap(IN SIZEL Size,
|
||||||
pso->cjBits = pso->lDelta * Size.cy;
|
pso->cjBits = pso->lDelta * Size.cy;
|
||||||
UncompressedFormat = BMF_8BPP;
|
UncompressedFormat = BMF_8BPP;
|
||||||
UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
|
UncompressedBits = EngAllocMem(FL_ZERO_MEMORY, pso->cjBits, TAG_DIB);
|
||||||
Decompress8bpp(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta);
|
DecompressBitmap(Size, (BYTE *)Bits, (BYTE *)UncompressedBits, pso->lDelta, Format);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -467,6 +427,7 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
|
||||||
PSURFACE psurf;
|
PSURFACE psurf;
|
||||||
SIZEL LocalSize;
|
SIZEL LocalSize;
|
||||||
BOOLEAN AllocatedLocally = FALSE;
|
BOOLEAN AllocatedLocally = FALSE;
|
||||||
|
PVOID DecompressedBits = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First, check the format so we can get the aligned scanline width.
|
* First, check the format so we can get the aligned scanline width.
|
||||||
|
@ -500,17 +461,29 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BMF_8RLE:
|
case BMF_8RLE:
|
||||||
case BMF_4RLE:
|
ScanLine = (BitmapInfo->Width + 3) & ~3;
|
||||||
case BMF_JPEG:
|
|
||||||
case BMF_PNG:
|
|
||||||
Compressed = TRUE;
|
Compressed = TRUE;
|
||||||
break;
|
break;
|
||||||
|
case BMF_4RLE:
|
||||||
|
ScanLine = ((BitmapInfo->Width + 7) & ~7) >> 1;
|
||||||
|
Compressed = TRUE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case BMF_JPEG:
|
||||||
|
case BMF_PNG:
|
||||||
|
ASSERT(FALSE); // ENGDDI shouldn't be creating PNGs for drivers ;-)
|
||||||
|
DPRINT1("No support for JPEG and PNG formats\n");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
DPRINT1("Invalid bitmap format\n");
|
DPRINT1("Invalid bitmap format\n");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save local bitmap size */
|
||||||
|
LocalSize.cy = BitmapInfo->Height;
|
||||||
|
LocalSize.cx = BitmapInfo->Width;
|
||||||
|
|
||||||
/* Does the device manage its own surface? */
|
/* Does the device manage its own surface? */
|
||||||
if (!Bits)
|
if (!Bits)
|
||||||
{
|
{
|
||||||
|
@ -519,7 +492,8 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
|
||||||
{
|
{
|
||||||
/* Note: we should not be seeing this scenario from ENGDDI */
|
/* Note: we should not be seeing this scenario from ENGDDI */
|
||||||
ASSERT(FALSE);
|
ASSERT(FALSE);
|
||||||
Size = BitmapInfo->Size;
|
DPRINT1("RLE compressed bitmap requested with no valid bitmap bits\n");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -551,6 +525,22 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
|
||||||
{
|
{
|
||||||
/* Should not have asked for user memory */
|
/* Should not have asked for user memory */
|
||||||
ASSERT((BitmapInfo->Flags & BMF_USERMEM) == 0);
|
ASSERT((BitmapInfo->Flags & BMF_USERMEM) == 0);
|
||||||
|
|
||||||
|
if (Compressed)
|
||||||
|
{
|
||||||
|
DecompressedBits = EngAllocMem(FL_ZERO_MEMORY, BitmapInfo->Height * ScanLine, TAG_DIB);
|
||||||
|
|
||||||
|
if(!DecompressedBits)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if(!DecompressBitmap(LocalSize, (BYTE *)Bits, (BYTE *)DecompressedBits, ScanLine, BitmapInfo->Format))
|
||||||
|
{
|
||||||
|
EngFreeMem(DecompressedBits);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BitmapInfo->Format = (BitmapInfo->Format == BMF_4RLE) ? BMF_4BPP : BMF_8BPP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate the actual surface object structure */
|
/* Allocate the actual surface object structure */
|
||||||
|
@ -564,6 +554,8 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
|
||||||
else
|
else
|
||||||
EngFreeMem(Bits);
|
EngFreeMem(Bits);
|
||||||
}
|
}
|
||||||
|
if (DecompressedBits)
|
||||||
|
EngFreeMem(DecompressedBits);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -584,8 +576,6 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
|
||||||
pso->fjBitmap = BitmapInfo->Flags & (BMF_TOPDOWN | BMF_UMPDMEM | BMF_USERMEM);
|
pso->fjBitmap = BitmapInfo->Flags & (BMF_TOPDOWN | BMF_UMPDMEM | BMF_USERMEM);
|
||||||
|
|
||||||
/* Save size and type */
|
/* Save size and type */
|
||||||
LocalSize.cy = BitmapInfo->Height;
|
|
||||||
LocalSize.cx = BitmapInfo->Width;
|
|
||||||
pso->sizlBitmap = LocalSize;
|
pso->sizlBitmap = LocalSize;
|
||||||
pso->iType = STYPE_BITMAP;
|
pso->iType = STYPE_BITMAP;
|
||||||
|
|
||||||
|
@ -601,11 +591,11 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
|
||||||
psurf->flHooks = 0;
|
psurf->flHooks = 0;
|
||||||
|
|
||||||
/* Set bits */
|
/* Set bits */
|
||||||
|
if(Compressed)
|
||||||
|
pso->pvBits = DecompressedBits;
|
||||||
|
else
|
||||||
pso->pvBits = Bits;
|
pso->pvBits = Bits;
|
||||||
|
|
||||||
/* Check for bitmap type */
|
|
||||||
if (!Compressed)
|
|
||||||
{
|
|
||||||
/* Number of bits is based on the height times the scanline */
|
/* Number of bits is based on the height times the scanline */
|
||||||
pso->cjBits = BitmapInfo->Height * ScanLine;
|
pso->cjBits = BitmapInfo->Height * ScanLine;
|
||||||
if (BitmapInfo->Flags & BMF_TOPDOWN)
|
if (BitmapInfo->Flags & BMF_TOPDOWN)
|
||||||
|
@ -620,26 +610,6 @@ SURFMEM_bCreateDib(IN PDEVBITMAPINFO BitmapInfo,
|
||||||
pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ScanLine);
|
pso->pvScan0 = (PVOID)((ULONG_PTR)pso->pvBits + pso->cjBits - ScanLine);
|
||||||
pso->lDelta = -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 */
|
/* Finally set the handle and uniq */
|
||||||
pso->hsurf = (HSURF)psurf->BaseObject.hHmgr;
|
pso->hsurf = (HSURF)psurf->BaseObject.hHmgr;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue