mirror of
https://github.com/reactos/reactos.git
synced 2025-07-04 17:01:22 +00:00
Evgeniy Boltik <bstsoft@narod.ru>
- Rework 8bit DIB alphablend to do alpha operations in source's palette (32bpp) to obtain much better output quality with lowest possible quality loss. See issue #4291 for more details. svn path=/trunk/; revision=40103
This commit is contained in:
parent
8d620098f5
commit
d9d83e8fb1
1 changed files with 30 additions and 55 deletions
|
@ -372,12 +372,12 @@ DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
|
||||||
register PUCHAR Dst;
|
register PUCHAR Dst;
|
||||||
ULONG DstDelta;
|
ULONG DstDelta;
|
||||||
BLENDFUNCTION BlendFunc;
|
BLENDFUNCTION BlendFunc;
|
||||||
register NICEPIXEL32 DstPixel;
|
register NICEPIXEL32 DstPixel32;
|
||||||
register NICEPIXEL32 SrcPixel;
|
register NICEPIXEL32 SrcPixel32;
|
||||||
register NICEPIXEL16 SrcPixel16;
|
register NICEPIXEL16 SrcPixel16;
|
||||||
UCHAR Alpha, SrcBpp;
|
UCHAR Alpha, SrcBpp;
|
||||||
HPALETTE SrcPalette, DstPalette;
|
XLATEGDI* XlateGDI;
|
||||||
XLATEOBJ *SrcTo32Xlate, *DstTo32Xlate, *DstFrom32Xlate;
|
XLATEOBJ* SrcXlateObj;
|
||||||
|
|
||||||
DPRINT("DIB_8BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
|
DPRINT("DIB_8BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
|
||||||
SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
|
SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
|
||||||
|
@ -408,35 +408,17 @@ DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
|
||||||
DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
|
DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
if (!ColorTranslation)
|
||||||
SrcBpp = BitsPerFormat(Source->iBitmapFormat);
|
|
||||||
SrcPalette = IntEngGetXlatePalette(ColorTranslation, XO_SRCPALETTE);
|
|
||||||
if (SrcPalette != 0)
|
|
||||||
{
|
{
|
||||||
SrcTo32Xlate = IntEngCreateXlate(PAL_RGB, 0, NULL, SrcPalette);
|
DPRINT1("ColorTranslation must not be NULL!\n");
|
||||||
if (SrcTo32Xlate == NULL)
|
return FALSE;
|
||||||
{
|
|
||||||
DPRINT1("IntEngCreateXlate failed\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SrcTo32Xlate = NULL;
|
|
||||||
ASSERT(SrcBpp >= 16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DstPalette = IntEngGetXlatePalette(ColorTranslation, XO_DESTPALETTE);
|
XlateGDI = ObjToGDI(ColorTranslation, XLATE);
|
||||||
DstTo32Xlate = IntEngCreateXlate(PAL_RGB, 0, NULL, DstPalette);
|
SrcXlateObj = IntEngCreateXlate(0, 0, XlateGDI->SourcePal, XlateGDI->DestPal);
|
||||||
DstFrom32Xlate = IntEngCreateXlate(0, PAL_RGB, DstPalette, NULL);
|
|
||||||
if (DstTo32Xlate == NULL || DstFrom32Xlate == NULL)
|
if (!SrcXlateObj)
|
||||||
{
|
{
|
||||||
if (SrcTo32Xlate != NULL)
|
|
||||||
EngDeleteXlate(SrcTo32Xlate);
|
|
||||||
if (DstTo32Xlate != NULL)
|
|
||||||
EngDeleteXlate(DstTo32Xlate);
|
|
||||||
if (DstFrom32Xlate != NULL)
|
|
||||||
EngDeleteXlate(DstFrom32Xlate);
|
|
||||||
DPRINT1("IntEngCreateXlate failed\n");
|
DPRINT1("IntEngCreateXlate failed\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
@ -444,6 +426,7 @@ DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
|
||||||
Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
|
Dst = (PUCHAR)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
|
||||||
DestRect->left);
|
DestRect->left);
|
||||||
DstDelta = Dest->lDelta - (DestRect->right - DestRect->left);
|
DstDelta = Dest->lDelta - (DestRect->right - DestRect->left);
|
||||||
|
SrcBpp = BitsPerFormat(Source->iBitmapFormat);
|
||||||
|
|
||||||
Rows = DestRect->bottom - DestRect->top;
|
Rows = DestRect->bottom - DestRect->top;
|
||||||
SrcY = SourceRect->top;
|
SrcY = SourceRect->top;
|
||||||
|
@ -453,45 +436,37 @@ DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
|
||||||
SrcX = SourceRect->left;
|
SrcX = SourceRect->left;
|
||||||
while (--Cols >= 0)
|
while (--Cols >= 0)
|
||||||
{
|
{
|
||||||
if (SrcTo32Xlate != NULL)
|
if (SrcBpp <= 16)
|
||||||
{
|
{
|
||||||
SrcPixel.ul = DIB_GetSource(Source, SrcX++, SrcY, SrcTo32Xlate);
|
SrcPixel16.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
|
||||||
}
|
SrcPixel32.col.red = (SrcPixel16.col.red << 3) | (SrcPixel16.col.red >> 2);
|
||||||
else if (SrcBpp <= 16)
|
SrcPixel32.col.green = (SrcPixel16.col.green << 2) | (SrcPixel16.col.green >> 4);
|
||||||
{
|
SrcPixel32.col.blue = (SrcPixel16.col.blue << 3) | (SrcPixel16.col.blue >> 2);
|
||||||
SrcPixel16.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
|
|
||||||
SrcPixel.col.red = (SrcPixel16.col.red << 3) | (SrcPixel16.col.red >> 2);
|
|
||||||
SrcPixel.col.green = (SrcPixel16.col.green << 2) | (SrcPixel16.col.green >> 4);
|
|
||||||
SrcPixel.col.blue = (SrcPixel16.col.blue << 3) | (SrcPixel16.col.blue >> 2);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SrcPixel.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY);
|
SrcPixel32.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY);
|
||||||
}
|
}
|
||||||
SrcPixel.col.red = SrcPixel.col.red * BlendFunc.SourceConstantAlpha / 255;
|
SrcPixel32.col.red = SrcPixel32.col.red * BlendFunc.SourceConstantAlpha / 255;
|
||||||
SrcPixel.col.green = SrcPixel.col.green * BlendFunc.SourceConstantAlpha / 255;
|
SrcPixel32.col.green = SrcPixel32.col.green * BlendFunc.SourceConstantAlpha / 255;
|
||||||
SrcPixel.col.blue = SrcPixel.col.blue * BlendFunc.SourceConstantAlpha / 255;
|
SrcPixel32.col.blue = SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha / 255;
|
||||||
SrcPixel.col.alpha = (SrcBpp == 32) ? (SrcPixel.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha;
|
SrcPixel32.col.alpha = (SrcBpp == 32) ? (SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) : BlendFunc.SourceConstantAlpha;
|
||||||
|
|
||||||
Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
|
Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
|
||||||
SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha;
|
SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha;
|
||||||
|
|
||||||
DstPixel.ul = XLATEOBJ_iXlate(DstTo32Xlate, *Dst);
|
DstPixel32.ul = XLATEOBJ_iXlate(SrcXlateObj, *Dst);
|
||||||
DstPixel.col.red = Clamp8(DstPixel.col.red * (255 - Alpha) / 255 + SrcPixel.col.red);
|
SrcPixel32.col.red = Clamp8(DstPixel32.col.red * (255 - Alpha) / 255 + SrcPixel32.col.red);
|
||||||
DstPixel.col.green = Clamp8(DstPixel.col.green * (255 - Alpha) / 255 + SrcPixel.col.green);
|
SrcPixel32.col.green = Clamp8(DstPixel32.col.green * (255 - Alpha) / 255 + SrcPixel32.col.green);
|
||||||
DstPixel.col.blue = Clamp8(DstPixel.col.blue * (255 - Alpha) / 255 + SrcPixel.col.blue);
|
SrcPixel32.col.blue = Clamp8(DstPixel32.col.blue * (255 - Alpha) / 255 + SrcPixel32.col.blue);
|
||||||
*Dst++ = XLATEOBJ_iXlate(DstFrom32Xlate, DstPixel.ul);
|
*Dst++ = XLATEOBJ_iXlate(ColorTranslation, SrcPixel32.ul);
|
||||||
}
|
}
|
||||||
Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta);
|
Dst = (PUCHAR)((ULONG_PTR)Dst + DstDelta);
|
||||||
SrcY++;
|
SrcY++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SrcTo32Xlate != NULL)
|
if (SrcXlateObj)
|
||||||
EngDeleteXlate(SrcTo32Xlate);
|
EngDeleteXlate(SrcXlateObj);
|
||||||
if (DstTo32Xlate != NULL)
|
|
||||||
EngDeleteXlate(DstTo32Xlate);
|
|
||||||
if (DstFrom32Xlate != NULL)
|
|
||||||
EngDeleteXlate(DstFrom32Xlate);
|
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue