public static byte[] DecodeDXT45Texture(int Width, int Height, byte[] SourceData) { DDS.Color.ColorRGBA[] Color = new DDS.Color.ColorRGBA[4]; DDS.Color.ColorRGBA CColor; int CData; byte[] DestData = new byte[(Width * Height) * 4]; int ChunksPerHLine = Width / 4; if (ChunksPerHLine == 0) { ChunksPerHLine = 1; } for (int i = 0; i < (Width * Height); i += 16) { Color[0] = DDS.Color.ShortToColor(SourceData[i + 8] | (SourceData[i + 9] << 8)); Color[1] = DDS.Color.ShortToColor(SourceData[i + 10] | (SourceData[i + 11] << 8)); Color[2] = DDS.Color.GradientColors(Color[0], Color[1]); Color[3] = DDS.Color.GradientColors(Color[1], Color[0]); CData = (SourceData[i + 12] << 0) | (SourceData[i + 13] << 8) | (SourceData[i + 14] << 16) | (SourceData[i + 15] << 24); byte[] Alpha = new byte[8]; Alpha[0] = SourceData[i]; Alpha[1] = SourceData[i + 1]; //Do the alphas if (Alpha[0] > Alpha[1]) { // 8-alpha block: derive the other six alphas. // Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated. Alpha[2] = (byte)((6 * Alpha[0] + 1 * Alpha[1] + 3) / 7); // bit code 010 Alpha[3] = (byte)((5 * Alpha[0] + 2 * Alpha[1] + 3) / 7); // bit code 011 Alpha[4] = (byte)((4 * Alpha[0] + 3 * Alpha[1] + 3) / 7); // bit code 100 Alpha[5] = (byte)((3 * Alpha[0] + 4 * Alpha[1] + 3) / 7); // bit code 101 Alpha[6] = (byte)((2 * Alpha[0] + 5 * Alpha[1] + 3) / 7); // bit code 110 Alpha[7] = (byte)((1 * Alpha[0] + 6 * Alpha[1] + 3) / 7); // bit code 111 } else { // 6-alpha block. // Bit code 000 = alpha_0, 001 = alpha_1, others are interpolated. Alpha[2] = (byte)((4 * Alpha[0] + 1 * Alpha[1] + 2) / 5); // Bit code 010 Alpha[3] = (byte)((3 * Alpha[0] + 2 * Alpha[1] + 2) / 5); // Bit code 011 Alpha[4] = (byte)((2 * Alpha[0] + 3 * Alpha[1] + 2) / 5); // Bit code 100 Alpha[5] = (byte)((1 * Alpha[0] + 4 * Alpha[1] + 2) / 5); // Bit code 101 Alpha[6] = 0; // Bit code 110 Alpha[7] = 255; // Bit code 111 } // Byte Alpha // 0 Alpha_0 // 1 Alpha_1 // 2 (0)(2) (2 LSBs), (0)(1), (0)(0) // 3 (1)(1) (1 LSB), (1)(0), (0)(3), (0)(2) (1 MSB) // 4 (1)(3), (1)(2), (1)(1) (2 MSBs) // 5 (2)(2) (2 LSBs), (2)(1), (2)(0) // 6 (3)(1) (1 LSB), (3)(0), (2)(3), (2)(2) (1 MSB) // 7 (3)(3), (3)(2), (3)(1) (2 MSBs) // (0 // Read an int and a short int tmpword = SourceData[i + 2] | (SourceData[i + 3] << 8); long tmpdword = SourceData[i + 4] | (SourceData[i + 5] << 8) | (SourceData[i + 6] << 16) | (SourceData[i + 7] << 24); long alphaDat = tmpword | (tmpdword << 16); int ChunkNum = i / 16; long XPos = ChunkNum % ChunksPerHLine; long YPos = (ChunkNum - XPos) / ChunksPerHLine; long ttmp; int sizeh = Height < 4 ? Height : 4; int sizew = Width < 4 ? Width : 4; int x, y; for (x = 0; x < sizeh; x++) { for (y = 0; y < sizew; y++) { CColor = Color[CData & 3]; CData >>= 2; CColor.a = Alpha[alphaDat & 7]; alphaDat >>= 3; ttmp = ((YPos * 4 + x) * Width + XPos * 4 + y) * 4; DestData[ttmp] = CColor.b; DestData[ttmp + 1] = CColor.g; DestData[ttmp + 2] = CColor.r; DestData[ttmp + 3] = CColor.a; } } } return(DestData); }
public static byte[] DecodeCubeDXT1(int width, int height, byte[] SourceData) { DDS.Color.ColorRGBA[] Color = new DDS.Color.ColorRGBA[5]; DDS.Color.ColorRGBA CColor; DDS.Color.ColorRGBA zeroColor; int CData; int c1; int c2; int dptr = 0; bool trans; byte[] DestData = new byte[(width * height) * 4]; int ChunksPerHLine = width / 4; if (ChunksPerHLine == 0) { ChunksPerHLine = 1; } for (int i = 0; i < (width * height); i += 16) { c1 = (SourceData[dptr + 1] << 8) | (SourceData[dptr]); c2 = (SourceData[dptr + 3] << 8) | (SourceData[dptr + 2]); trans = (!(c1 > c2)); Color[0] = DDS.Color.ShortToColor(c1); Color[1] = DDS.Color.ShortToColor(c2); if (!trans) { Color[2] = DDS.Color.GradientColors(Color[0], Color[1]); Color[3] = DDS.Color.GradientColors(Color[1], Color[0]); } else { zeroColor = Color[0]; Color[2] = DDS.Color.GradientColorsHalf(Color[0], Color[1]); Color[3] = zeroColor; } CData = (SourceData[dptr + 4] << 0) | (SourceData[dptr + 5] << 8) | (SourceData[dptr + 6] << 16) | (SourceData[dptr + 7] << 24); int ChunkNum = i / 16; long XPos = ChunkNum % ChunksPerHLine; long YPos = (ChunkNum - XPos) / ChunksPerHLine; long tmp1, tmp2; int sizeh = height < 4 ? height : 4; int sizew = width < 4 ? width : 4; int x, y; for (x = 0; x < sizeh; x++) { for (y = 0; y < sizew; y++) { CColor = Color[CData & 3]; CData >>= 2; tmp1 = ((YPos * 4 + x) * width + XPos * 4 + y) * 4; tmp2 = DDS.Color.ColorToInt(CColor); DestData[tmp1] = CColor.b; DestData[tmp1 + 1] = CColor.g; DestData[tmp1 + 2] = CColor.r; DestData[tmp1 + 3] = CColor.a; } } dptr += 8; } return(DestData); }
public static byte[] DecodeDXT23Texture(int Width, int Height, byte[] SourceData) { DDS.Color.ColorRGBA[] Color = new DDS.Color.ColorRGBA[5]; DDS.Color.ColorRGBA CColor; DDS.Color.ColorRGBA c1, c2, c3, c4; int CData; byte[] DestData = new byte[(Width * Height) * 4]; int ChunksPerHLine = Width / 4; if (ChunksPerHLine == 0) { ChunksPerHLine = 1; } for (int i = 0; i < (Width * Height); i += 16) { c1 = DDS.Color.ShortToColor((SourceData[i + 8]) | (SourceData[i + 9] << 8)); c2 = DDS.Color.ShortToColor((SourceData[i + 10]) | (SourceData[i + 11] << 8)); c3 = DDS.Color.GradientColors(Color[0], Color[1]); c4 = DDS.Color.GradientColors(Color[1], Color[0]); Color[0] = c1; Color[1] = c2; Color[2] = c3; Color[3] = c4; CData = (SourceData[i + 12] << 0) | (SourceData[i + 13] << 8) | (SourceData[i + 14] << 16) | (SourceData[i + 15] << 24); int ChunkNum = i / 16; long XPos = ChunkNum % ChunksPerHLine; long YPos = (ChunkNum - XPos) / ChunksPerHLine; long ttmp; int alpha; int sizeh = Height < 4 ? Height : 4; int sizew = Width < 4 ? Width : 4; int x, y; for (x = 0; x < sizeh; x++) { alpha = SourceData[i + (2 * x)] | (SourceData[i + (2 * x) + 1]) << 8; for (y = 0; y < sizew; y++) { CColor = Color[CData & 3]; CData >>= 2; CColor.a = (byte)((alpha & 15) * 16); alpha >>= 4; ttmp = ((YPos * 4 + x) * Width + XPos * 4 + y) * 4; DestData[ttmp] = CColor.b; DestData[ttmp + 1] = CColor.g; DestData[ttmp + 2] = CColor.r; DestData[ttmp + 3] = CColor.a; } } } return(DestData); }