freebsd-ports/graphics/devil/files/patch-41
Mikhail Teterin 226a727f0b Make buildable with clang. While here, add patches submitted upstream
by others. Also make use of the author's own self-test suit.

PR:		196161
Approved by:	maintainer timeout
2016-03-01 00:49:27 +00:00

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++)