Author: fireball
Date: Tue Mar 17 21:00:28 2009
New Revision: 40074
URL:
http://svn.reactos.org/svn/reactos?rev=40074&view=rev
Log:
Evgeniy Boltik <bstsoft(a)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.
Modified:
trunk/reactos/subsystems/win32/win32k/dib/dib16bpp.c
Modified: trunk/reactos/subsystems/win32/win32k/dib/dib16bpp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/di…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/dib/dib16bpp.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/dib/dib16bpp.c [iso-8859-1] Tue Mar 17 21:00:28
2009
@@ -541,6 +541,12 @@
}
static __inline UCHAR
+Clamp8(ULONG val)
+{
+ return (val > 255) ? 255 : val;
+}
+
+static __inline UCHAR
Clamp6(ULONG val)
{
return (val > 63) ? 63 : val;
@@ -555,9 +561,13 @@
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,
@@ -586,6 +596,21 @@
BitsPerFormat(Source->iBitmapFormat) != 32)
{
DPRINT1("Source bitmap must be 32bpp when AC_SRC_ALPHA is set\n");
+ 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;
}
@@ -604,52 +629,61 @@
{
if (SrcBpp <= 16)
{
- DstPixel.us = DIB_GetSource(Source, SrcX++, SrcY, ColorTranslation);
- SrcPixel.col.red = (DstPixel.col.red << 3) | (DstPixel.col.red
>> 2);
-
- SrcPixel.col.green = (DstPixel.col.green << 2) |
- (DstPixel.col.green >> 4);
-
- SrcPixel.col.blue = (DstPixel.col.blue << 3) | (DstPixel.col.blue
>> 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);
+
+ 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;
+
+ 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);
- }
- 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;
+ 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);
+ }
}
Dst = (PUSHORT)((ULONG_PTR)Dst + DstDelta);
SrcY++;
}
+ if (SrcXlateObj) EngDeleteXlate(SrcXlateObj);
+
return TRUE;
}