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@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/dib... ============================================================================== --- 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; }