private void UnpackDXTAlpha(DXTInterpolatedAlphaBlock block, ColorEx[] pCol)
{
// 8 derived alpha values to be indexed
Real[] derivedAlphas = new Real[8];
// Explicit extremes
derivedAlphas[ 0 ] = block.Alpha0 / (Real)0xFF;
derivedAlphas[ 1 ] = block.Alpha1 / (Real)0xFF;
if ( block.Alpha0 <= block.Alpha1 )
{
// 4 interpolated alphas, plus zero and one
// full range including extremes at [0] and [5]
// we want to fill in [1] through [4] at weights ranging
// from 1/5 to 4/5
Real denom = 1.0f / 5.0f;
for ( int i = 0; i < 4; ++i )
{
Real factor0 = ( 4 - i ) * denom;
Real factor1 = ( i + 1 ) * denom;
derivedAlphas[ i + 2 ] =
( factor0 * block.Alpha0 ) + ( factor1 * block.Alpha1 );
}
derivedAlphas[ 6 ] = 0.0f;
derivedAlphas[ 7 ] = 1.0f;
}
else
{
// 6 interpolated alphas
// full range including extremes at [0] and [7]
// we want to fill in [1] through [6] at weights ranging
// from 1/7 to 6/
Real denom = 1.0f / 7.0f;
for ( int i = 0; i < 6; ++i )
{
Real factor0 = ( 6 - i ) * denom;
Real factor1 = ( i + 1 ) * denom;
derivedAlphas[ i + 2 ] =
( factor0 * block.Alpha0 ) + ( factor1 * block.Alpha1 );
}
}
// Ok, now we've built the reference values, process the indexes
for ( int i = 0; i < 16; ++i )
{
int baseByte = ( i * 3 ) / 8;
int baseBit = ( i * 3 ) % 8;
int bits = ( block.Indexes[ baseByte ] >> baseBit & 0x7 );
// do we need to stitch in next byte too?
if ( baseBit > 5 )
{
int extraBits = ( block.Indexes[ baseByte + 1 ] << ( 8 - baseBit ) ) & 0xFF;
bits |= extraBits & 0x7;
}
pCol[ i ].a = derivedAlphas[ bits ];
}
}