mirror of
https://github.com/reactos/reactos.git
synced 2025-04-26 00:20:34 +00:00
Evgeniy Boltik <bstsoft@narod.ru>
- Rework 16bit DIB alphablend to do alpha operations in source's palette (32bpp) to obtain much better output quality without data loss. See issue #3708 for more details. svn path=/trunk/; revision=40074
This commit is contained in:
parent
cf3d6a794f
commit
64b42346d2
1 changed files with 70 additions and 36 deletions
|
@ -540,6 +540,12 @@ Clamp5(ULONG val)
|
|||
return (val > 31) ? 31 : val;
|
||||
}
|
||||
|
||||
static __inline UCHAR
|
||||
Clamp8(ULONG val)
|
||||
{
|
||||
return (val > 255) ? 255 : val;
|
||||
}
|
||||
|
||||
static __inline UCHAR
|
||||
Clamp6(ULONG val)
|
||||
{
|
||||
|
@ -555,9 +561,13 @@ DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
|
|||
register PUSHORT Dst;
|
||||
ULONG DstDelta;
|
||||
BLENDFUNCTION BlendFunc;
|
||||
register NICEPIXEL16 DstPixel;
|
||||
register NICEPIXEL32 SrcPixel;
|
||||
register NICEPIXEL16 SrcPixel16;
|
||||
register NICEPIXEL16 DstPixel16;
|
||||
register NICEPIXEL32 SrcPixel32;
|
||||
register NICEPIXEL32 DstPixel32;
|
||||
UCHAR Alpha, SrcBpp;
|
||||
XLATEGDI* XlateGDI;
|
||||
XLATEOBJ* SrcXlateObj;
|
||||
|
||||
DPRINT("DIB_16BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
|
||||
SourceRect->left, SourceRect->top, SourceRect->right, SourceRect->bottom,
|
||||
|
@ -589,6 +599,21 @@ DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (!ColorTranslation)
|
||||
{
|
||||
DPRINT1("ColorTranslation must not be NULL!\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
XlateGDI = ObjToGDI(ColorTranslation, XLATE);
|
||||
SrcXlateObj = IntEngCreateXlate(0, 0, XlateGDI->SourcePal, XlateGDI->DestPal);
|
||||
|
||||
if (!SrcXlateObj)
|
||||
{
|
||||
DPRINT1("IntEngCreateXlate failed\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Dst = (PUSHORT)((ULONG_PTR)Dest->pvScan0 + (DestRect->top * Dest->lDelta) +
|
||||
(DestRect->left << 1));
|
||||
DstDelta = Dest->lDelta - ((DestRect->right - DestRect->left) << 1);
|
||||
|
@ -604,52 +629,61 @@ DIB_16BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
|
|||
{
|
||||
if (SrcBpp <= 16)
|
||||
{
|
||||
DstPixel.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
|
||||
SrcPixel.col.red = (DstPixel.col.red << 3) | (DstPixel.col.red >> 2);
|
||||
SrcPixel16.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
|
||||
SrcPixel32.col.red = (SrcPixel16.col.red << 3);
|
||||
SrcPixel32.col.green = (SrcPixel16.col.green << 2);
|
||||
SrcPixel32.col.blue = (SrcPixel16.col.blue << 3);
|
||||
|
||||
SrcPixel.col.green = (DstPixel.col.green << 2) |
|
||||
(DstPixel.col.green >> 4);
|
||||
SrcPixel32.col.red = SrcPixel32.col.red * BlendFunc.SourceConstantAlpha / 255;
|
||||
SrcPixel32.col.green = SrcPixel32.col.green * BlendFunc.SourceConstantAlpha / 255;
|
||||
SrcPixel32.col.blue = SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha / 255;
|
||||
SrcPixel32.col.alpha = (SrcBpp == 32) ?
|
||||
(SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) :
|
||||
BlendFunc.SourceConstantAlpha;
|
||||
|
||||
SrcPixel.col.blue = (DstPixel.col.blue << 3) | (DstPixel.col.blue >> 2);
|
||||
Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
|
||||
SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha;
|
||||
|
||||
DstPixel16.us = *Dst;
|
||||
DstPixel16.col.red = Clamp5(DstPixel16.col.red * (255 - Alpha) / 255 +
|
||||
(SrcPixel32.col.red >> 3));
|
||||
|
||||
DstPixel16.col.green = Clamp6(DstPixel16.col.green * (255 - Alpha) / 255 +
|
||||
(SrcPixel32.col.green >> 2));
|
||||
|
||||
DstPixel16.col.blue = Clamp5(DstPixel16.col.blue * (255 - Alpha) / 255 +
|
||||
(SrcPixel32.col.blue >> 3));
|
||||
|
||||
*Dst++ = DstPixel16.us;
|
||||
}
|
||||
else
|
||||
{
|
||||
SrcPixel.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY);
|
||||
SrcPixel32.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY);
|
||||
|
||||
SrcPixel32.col.red = SrcPixel32.col.red * BlendFunc.SourceConstantAlpha / 255;
|
||||
SrcPixel32.col.green = SrcPixel32.col.green * BlendFunc.SourceConstantAlpha / 255;
|
||||
SrcPixel32.col.blue = SrcPixel32.col.blue * BlendFunc.SourceConstantAlpha / 255;
|
||||
SrcPixel32.col.alpha = (SrcBpp == 32) ?
|
||||
(SrcPixel32.col.alpha * BlendFunc.SourceConstantAlpha / 255) :
|
||||
BlendFunc.SourceConstantAlpha;
|
||||
|
||||
Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
|
||||
SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha;
|
||||
|
||||
DstPixel32.ul = XLATEOBJ_iXlate(SrcXlateObj, *Dst);
|
||||
SrcPixel32.col.red = Clamp8(DstPixel32.col.red * (255 - Alpha) / 255 + SrcPixel32.col.red);
|
||||
SrcPixel32.col.green = Clamp8(DstPixel32.col.green * (255 - Alpha) / 255 + SrcPixel32.col.green);
|
||||
SrcPixel32.col.blue = Clamp8(DstPixel32.col.blue * (255 - Alpha) / 255 + SrcPixel32.col.blue);
|
||||
*Dst++ = XLATEOBJ_iXlate(ColorTranslation, SrcPixel32.ul);
|
||||
}
|
||||
SrcPixel.col.red = SrcPixel.col.red *
|
||||
BlendFunc.SourceConstantAlpha / 255;
|
||||
|
||||
SrcPixel.col.green = SrcPixel.col.green *
|
||||
BlendFunc.SourceConstantAlpha / 255;
|
||||
|
||||
SrcPixel.col.blue = SrcPixel.col.blue *
|
||||
BlendFunc.SourceConstantAlpha / 255;
|
||||
|
||||
SrcPixel.col.alpha = (SrcBpp == 32) ?
|
||||
(SrcPixel.col.alpha *
|
||||
BlendFunc.SourceConstantAlpha / 255) :
|
||||
BlendFunc.SourceConstantAlpha;
|
||||
|
||||
Alpha = ((BlendFunc.AlphaFormat & AC_SRC_ALPHA) != 0) ?
|
||||
SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha;
|
||||
|
||||
DstPixel.us = *Dst;
|
||||
DstPixel.col.red = Clamp5(DstPixel.col.red * (255 - Alpha) / 255 +
|
||||
(SrcPixel.col.red >> 3));
|
||||
|
||||
DstPixel.col.green = Clamp6(DstPixel.col.green * (255 - Alpha) / 255 +
|
||||
(SrcPixel.col.green >> 2));
|
||||
|
||||
DstPixel.col.blue = Clamp5(DstPixel.col.blue * (255 - Alpha) / 255 +
|
||||
(SrcPixel.col.blue >> 3));
|
||||
|
||||
*Dst++ = DstPixel.us;
|
||||
}
|
||||
|
||||
Dst = (PUSHORT)((ULONG_PTR)Dst + DstDelta);
|
||||
SrcY++;
|
||||
}
|
||||
|
||||
if (SrcXlateObj) EngDeleteXlate(SrcXlateObj);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue