// BC5
internal static void DecompressATI2Block(byte[] source, int sourceStart, byte[] destination, int decompressedStart, int decompressedLineLength, bool unused)
{
// Green = +1
DDS_BlockHelpers.Decompress8BitBlock(source, sourceStart, destination, decompressedStart + 1, decompressedLineLength, false);
// Red = +2, source + 8 to skip first compressed block.
DDS_BlockHelpers.Decompress8BitBlock(source, sourceStart + 8, destination, decompressedStart + 2, decompressedLineLength, false);
// KFreon: Alpha is 255, and blue needs to be calculated
for (int i = 0; i < 16; i++)
{
int offset = GetDecompressedOffset(decompressedStart, decompressedLineLength, i);
// Get Red and Green on the range -1 - 1
// *2-1 moves the range from 0 - 1, to -1 - 1
double green = (destination[offset + 1] / 127.5d) - 1d;
double red = (destination[offset + 2] / 127.5d) - 1d;
// Z solution for: x2 + y2 + z2 = 1, unit normal vectors. Only consider +ve root as ATI2 is a tangent space mapping and Z must be +ve.
// Also when 1 - x2 - y2 < 0, Z = NaN, but is compensated for in ExpandTo255.
double Z = Math.Sqrt(1d - (red * red + green * green));
destination[offset] = ExpandTo255(Z); // Blue
destination[offset + 3] = 255; // Alpha
}
}