by others. Also make use of the author's own self-test suit. PR: 196161 Approved by: maintainer timeout
103 lines
3.7 KiB
Text
103 lines
3.7 KiB
Text
See https://sourceforge.net/p/openil/patches/41/
|
|
|
|
This patch improves alpha-compositing in DevIL.
|
|
|
|
--- src-IL/src/il_devil.c (revision 1654)
|
|
+++ src-IL/src/il_devil.c (working copy)
|
|
@@ -665,10 +665,10 @@
|
|
ILuint c;
|
|
ILuint StartX, StartY, StartZ;
|
|
ILboolean DestFlipped = IL_FALSE;
|
|
+ ILboolean DoAlphaBlend = IL_FALSE;
|
|
ILubyte *SrcTemp;
|
|
- ILfloat Back;
|
|
-
|
|
- // Check if the desiination image really exists
|
|
+ ILfloat ResultAlpha;
|
|
+ // Check if the destination image really exists
|
|
if (DestName == 0 || iCurImage == NULL) {
|
|
ilSetError(IL_ILLEGAL_OPERATION);
|
|
return IL_FALSE;
|
|
@@ -680,6 +680,9 @@
|
|
DestFlipped = IL_TRUE;
|
|
ilFlipImage();
|
|
}
|
|
+ //determining destination alpha support
|
|
+ DoAlphaBlend = ilIsEnabled(IL_BLIT_BLEND);
|
|
+
|
|
//DestOrigin = Dest->Origin;
|
|
ilBindImage(Source);
|
|
|
|
@@ -688,7 +691,9 @@
|
|
ilSetError(IL_INVALID_PARAM);
|
|
return IL_FALSE;
|
|
}
|
|
-
|
|
+ //determining source alpha support
|
|
+ DoAlphaBlend &= ilIsEnabled(IL_BLIT_BLEND);
|
|
+
|
|
Src = iCurImage;
|
|
|
|
//@TODO test if coordinates are inside the images (hard limit for source)
|
|
@@ -737,38 +742,49 @@
|
|
const ILuint SrcIndex = (z+SrcZ)*ConvSizePlane + (y+SrcY)*ConvBps + (x+SrcX)*Dest->Bpp;
|
|
const ILuint DestIndex = (z+DestZ)*Dest->SizeOfPlane + (y+DestY)*Dest->Bps + (x+DestX)*Dest->Bpp;
|
|
const ILuint AlphaIdx = SrcIndex + bpp_without_alpha;
|
|
- ILfloat Front = 0;
|
|
+ ILfloat FrontAlpha = 0; // foreground opacity
|
|
+ ILfloat BackAlpha = 0; // background opacity
|
|
|
|
switch (Dest->Type)
|
|
{
|
|
case IL_BYTE:
|
|
case IL_UNSIGNED_BYTE:
|
|
- Front = Converted[AlphaIdx]/((float)IL_MAX_UNSIGNED_BYTE);
|
|
+ FrontAlpha = Converted[AlphaIdx]/((float)IL_MAX_UNSIGNED_BYTE);
|
|
+ BackAlpha = Dest->Data[AlphaIdx]/((float)IL_MAX_UNSIGNED_BYTE);
|
|
break;
|
|
case IL_SHORT:
|
|
case IL_UNSIGNED_SHORT:
|
|
- Front = ((ILshort*)Converted)[AlphaIdx]/((float)IL_MAX_UNSIGNED_SHORT);
|
|
+ FrontAlpha = ((ILshort*)Converted)[AlphaIdx]/((float)IL_MAX_UNSIGNED_SHORT);
|
|
+ BackAlpha = ((ILshort*)Dest->Data)[AlphaIdx]/((float)IL_MAX_UNSIGNED_SHORT);
|
|
break;
|
|
case IL_INT:
|
|
case IL_UNSIGNED_INT:
|
|
- Front = ((ILint*)Converted)[AlphaIdx]/((float)IL_MAX_UNSIGNED_INT);
|
|
+ FrontAlpha = ((ILint*)Converted)[AlphaIdx]/((float)IL_MAX_UNSIGNED_INT);
|
|
+ BackAlpha = ((ILint*)Dest->Data)[AlphaIdx]/((float)IL_MAX_UNSIGNED_INT);
|
|
break;
|
|
case IL_FLOAT:
|
|
- Front = ((ILfloat*)Converted)[AlphaIdx];
|
|
+ FrontAlpha = ((ILfloat*)Converted)[AlphaIdx];
|
|
+ BackAlpha = ((ILfloat*)Dest->Data)[AlphaIdx];
|
|
break;
|
|
case IL_DOUBLE:
|
|
- Front = (ILfloat)(((ILdouble*)Converted)[AlphaIdx]);
|
|
+ FrontAlpha = (ILfloat)(((ILdouble*)Converted)[AlphaIdx]);
|
|
+ BackAlpha = (ILfloat)(((ILdouble*)Dest->Data)[AlphaIdx]);
|
|
break;
|
|
}
|
|
- Back = 1.0f - Front;
|
|
- // In case of Alpha channel, the data is blended. Keeps the original alpha.
|
|
- if (ilIsEnabled(IL_BLIT_BLEND)) {
|
|
+
|
|
+ // In case of Alpha channel, the data is blended.
|
|
+ // Computes composite Alpha
|
|
+ if (DoAlphaBlend)
|
|
+ {
|
|
+ ResultAlpha = FrontAlpha + (1.0f - FrontAlpha) * BackAlpha;
|
|
for (c = 0; c < bpp_without_alpha; c++)
|
|
{
|
|
- Dest->Data[DestIndex + c] =
|
|
- (ILubyte)(Converted[SrcIndex + c] * Front
|
|
- + Dest->Data[DestIndex + c] * Back);
|
|
+ Dest->Data[DestIndex + c] = (ILubyte)( 0.5f +
|
|
+ (Converted[SrcIndex + c] * FrontAlpha +
|
|
+ (1.0f - FrontAlpha) * Dest->Data[DestIndex + c] * BackAlpha)
|
|
+ / ResultAlpha);
|
|
}
|
|
+ Dest->Data[AlphaIdx] = (ILubyte)(0.5f + ResultAlpha * (float)IL_MAX_UNSIGNED_BYTE);
|
|
}
|
|
else {
|
|
for (c = 0; c < Dest->Bpp; c++)
|