mirror of
https://github.com/reactos/reactos.git
synced 2025-02-24 17:34:57 +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;
|
||||
ULONG DstDelta;
|
||||
BLENDFUNCTION BlendFunc;
|
||||
register NICEPIXEL32 DstPixel;
|
||||
register NICEPIXEL32 SrcPixel;
|
||||
register NICEPIXEL32 DstPixel32;
|
||||
register NICEPIXEL32 SrcPixel32;
|
||||
register NICEPIXEL16 SrcPixel16;
|
||||
UCHAR Alpha, SrcBpp;
|
||||
HPALETTE SrcPalette, DstPalette;
|
||||
XLATEOBJ *SrcTo32Xlate, *DstTo32Xlate, *DstFrom32Xlate;
|
||||
XLATEGDI* XlateGDI;
|
||||
XLATEOBJ* SrcXlateObj;
|
||||
|
||||
DPRINT("DIB_8BPP_AlphaBlend: srcRect: (%d,%d)-(%d,%d), dstRect: (%d,%d)-(%d,%d)\n",
|
||||
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");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
SrcBpp = BitsPerFormat(Source->iBitmapFormat);
|
||||
SrcPalette = IntEngGetXlatePalette(ColorTranslation, XO_SRCPALETTE);
|
||||
if (SrcPalette != 0)
|
||||
if (!ColorTranslation)
|
||||
{
|
||||
SrcTo32Xlate = IntEngCreateXlate(PAL_RGB, 0, NULL, SrcPalette);
|
||||
if (SrcTo32Xlate == NULL)
|
||||
{
|
||||
DPRINT1("IntEngCreateXlate failed\n");
|
||||
DPRINT1("ColorTranslation must not be NULL!\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SrcTo32Xlate = NULL;
|
||||
ASSERT(SrcBpp >= 16);
|
||||
}
|
||||
|
||||
DstPalette = IntEngGetXlatePalette(ColorTranslation, XO_DESTPALETTE);
|
||||
DstTo32Xlate = IntEngCreateXlate(PAL_RGB, 0, NULL, DstPalette);
|
||||
DstFrom32Xlate = IntEngCreateXlate(0, PAL_RGB, DstPalette, NULL);
|
||||
if (DstTo32Xlate == NULL || DstFrom32Xlate == NULL)
|
||||
XlateGDI = ObjToGDI(ColorTranslation, XLATE);
|
||||
SrcXlateObj = IntEngCreateXlate(0, 0, XlateGDI->SourcePal, XlateGDI->DestPal);
|
||||
|
||||
if (!SrcXlateObj)
|
||||
{
|
||||
if (SrcTo32Xlate != NULL)
|
||||
EngDeleteXlate(SrcTo32Xlate);
|
||||
if (DstTo32Xlate != NULL)
|
||||
EngDeleteXlate(DstTo32Xlate);
|
||||
if (DstFrom32Xlate != NULL)
|
||||
EngDeleteXlate(DstFrom32Xlate);
|
||||
DPRINT1("IntEngCreateXlate failed\n");
|
||||
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) +
|
||||
DestRect->left);
|
||||
DstDelta = Dest->lDelta - (DestRect->right - DestRect->left);
|
||||
SrcBpp = BitsPerFormat(Source->iBitmapFormat);
|
||||
|
||||
Rows = DestRect->bottom - DestRect->top;
|
||||
SrcY = SourceRect->top;
|
||||
|
@ -453,45 +436,37 @@ DIB_8BPP_AlphaBlend(SURFOBJ* Dest, SURFOBJ* Source, RECTL* DestRect,
|
|||
SrcX = SourceRect->left;
|
||||
while (--Cols >= 0)
|
||||
{
|
||||
if (SrcTo32Xlate != NULL)
|
||||
{
|
||||
SrcPixel.ul = DIB_GetSource(Source, SrcX++, SrcY, SrcTo32Xlate);
|
||||
}
|
||||
else if (SrcBpp <= 16)
|
||||
if (SrcBpp <= 16)
|
||||
{
|
||||
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);
|
||||
SrcPixel32.col.red = (SrcPixel16.col.red << 3) | (SrcPixel16.col.red >> 2);
|
||||
SrcPixel32.col.green = (SrcPixel16.col.green << 2) | (SrcPixel16.col.green >> 4);
|
||||
SrcPixel32.col.blue = (SrcPixel16.col.blue << 3) | (SrcPixel16.col.blue >> 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
SrcPixel.ul = DIB_GetSourceIndex(Source, SrcX++, SrcY);
|
||||
SrcPixel32.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;
|
||||
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) ?
|
||||
SrcPixel.col.alpha : BlendFunc.SourceConstantAlpha;
|
||||
SrcPixel32.col.alpha : BlendFunc.SourceConstantAlpha;
|
||||
|
||||
DstPixel.ul = XLATEOBJ_iXlate(DstTo32Xlate, *Dst);
|
||||
DstPixel.col.red = Clamp8(DstPixel.col.red * (255 - Alpha) / 255 + SrcPixel.col.red);
|
||||
DstPixel.col.green = Clamp8(DstPixel.col.green * (255 - Alpha) / 255 + SrcPixel.col.green);
|
||||
DstPixel.col.blue = Clamp8(DstPixel.col.blue * (255 - Alpha) / 255 + SrcPixel.col.blue);
|
||||
*Dst++ = XLATEOBJ_iXlate(DstFrom32Xlate, DstPixel.ul);
|
||||
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 = (PUCHAR)((ULONG_PTR)Dst + DstDelta);
|
||||
SrcY++;
|
||||
}
|
||||
|
||||
if (SrcTo32Xlate != NULL)
|
||||
EngDeleteXlate(SrcTo32Xlate);
|
||||
if (DstTo32Xlate != NULL)
|
||||
EngDeleteXlate(DstTo32Xlate);
|
||||
if (DstFrom32Xlate != NULL)
|
||||
EngDeleteXlate(DstFrom32Xlate);
|
||||
if (SrcXlateObj)
|
||||
EngDeleteXlate(SrcXlateObj);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue