internal static void ReadUncompressed(byte[] source, int sourceStart, byte[] destination, int pixelCount, DDS_Header.DDS_PIXELFORMAT ddspf)
{
int signedAdjustment = ((ddspf.dwFlags & DDS_Header.DDS_PFdwFlags.DDPF_SIGNED) == DDS_Header.DDS_PFdwFlags.DDPF_SIGNED) ? SignedAdjustment : 0;
int sourceIncrement = ddspf.dwRGBBitCount / 8; // /8 for bits to bytes conversion
bool oneChannel = (ddspf.dwFlags & DDS_Header.DDS_PFdwFlags.DDPF_LUMINANCE) == DDS_Header.DDS_PFdwFlags.DDPF_LUMINANCE;
bool twoChannel = (ddspf.dwFlags & DDS_Header.DDS_PFdwFlags.DDPF_ALPHAPIXELS) == DDS_Header.DDS_PFdwFlags.DDPF_ALPHAPIXELS && oneChannel;
uint AMask = ddspf.dwABitMask;
uint RMask = ddspf.dwRBitMask;
uint GMask = ddspf.dwGBitMask;
uint BMask = ddspf.dwBBitMask;
///// Figure out channel existance and ordering.
// Setup array that indicates channel offset from pixel start.
// e.g. Alpha is usually first, and is given offset 0.
// NOTE: Ordering array is in ARGB order, and the stored indices change depending on detected channel order.
// A negative index indicates channel doesn't exist in data and sets channel to 0xFF.
List<uint> maskOrder = new List<uint>(4) { AMask, RMask, GMask, BMask };
maskOrder.Sort();
maskOrder.RemoveAll(t => t == 0); // Required, otherwise indicies get all messed up when there's only two channels, but it's not indicated as such.
int AIndex = 0;
int RIndex = 0;
int GIndex = 0;
int BIndex = 0;
if (twoChannel) // Note: V8U8 does not come under this one.
{
// Intensity is first byte, then the alpha. Set all RGB to intensity for grayscale.
// Second mask is always RMask as determined by the DDS Spec.
AIndex = AMask > RMask ? 1 : 0;
RIndex = AMask > RMask ? 0 : 1;
GIndex = AMask > RMask ? 0 : 1;
BIndex = AMask > RMask ? 0 : 1;
}
else if (oneChannel)
{
// Decide whether it's alpha or not.
AIndex = AMask == 0 ? -1 : 0;
RIndex = AMask == 0 ? 0 : -1;
GIndex = AMask == 0 ? 0 : -1;
BIndex = AMask == 0 ? 0 : -1;
}
else
{
// Set default ordering
AIndex = AMask == 0 ? -1 : maskOrder.IndexOf(AMask);
RIndex = RMask == 0 ? -1 : maskOrder.IndexOf(RMask);
GIndex = GMask == 0 ? -1 : maskOrder.IndexOf(GMask);
BIndex = BMask == 0 ? -1 : maskOrder.IndexOf(BMask);
}
for (int i = 0, j = sourceStart; i < pixelCount * 4; i += 4, j += sourceIncrement)
{
destination[i] = BIndex == -1 ? (byte)0xFF : (byte)(source[j + BIndex] - signedAdjustment);
destination[i + 1] = GIndex == -1 ? (byte)0xFF : (byte)(source[j + GIndex] - signedAdjustment);
destination[i + 2] = RIndex == -1 ? (byte)0xFF : (byte)(source[j + RIndex] - signedAdjustment);
destination[i + 3] = AIndex == -1 ? (byte)0xFF : (source[j + AIndex]);
}
}