public static Color ReadColor(BinaryReader BR, int BitDepth) { switch (BitDepth) { case 16: return(Graphic.DecodeRGB565(BR.ReadUInt16())); case 32: case 24: { int B = BR.ReadByte(); int G = BR.ReadByte(); int R = BR.ReadByte(); int A = 255; if (BitDepth == 32) { byte SemiAlpha = BR.ReadByte(); if (SemiAlpha < 0x80) { A = 2 * SemiAlpha; } } return(Color.FromArgb(A, R, G, B)); } case 8: { int GrayScale = BR.ReadByte(); return(Color.FromArgb(GrayScale, GrayScale, GrayScale)); } default: return(Color.HotPink); } }
private Color[] ReadTexelBlock(BinaryReader BR, string FourCC) { ulong AlphaBlock = 0; if (FourCC == "DXT2" || FourCC == "DXT3" || FourCC == "DXT4" || FourCC == "DXT5") { AlphaBlock = BR.ReadUInt64(); } else if (FourCC != "DXT1") { return(null); } ushort C0 = BR.ReadUInt16(); ushort C1 = BR.ReadUInt16(); Color[] Colors = new Color[4]; Colors[0] = Graphic.DecodeRGB565(C0); Colors[1] = Graphic.DecodeRGB565(C1); if (C0 > C1 || FourCC != "DXT1") { // opaque, 4-color Colors[2] = Color.FromArgb((2 * Colors[0].R + Colors[1].R + 1) / 3, (2 * Colors[0].G + Colors[1].G + 1) / 3, (2 * Colors[0].B + Colors[1].B + 1) / 3); Colors[3] = Color.FromArgb((2 * Colors[1].R + Colors[0].R + 1) / 3, (2 * Colors[1].G + Colors[0].G + 1) / 3, (2 * Colors[1].B + Colors[0].B + 1) / 3); } else { // 1-bit alpha, 3-color Colors[2] = Color.FromArgb((Colors[0].R + Colors[1].R) / 2, (Colors[0].G + Colors[1].G) / 2, (Colors[0].B + Colors[1].B) / 2); Colors[3] = Color.Transparent; } uint CompressedColor = BR.ReadUInt32(); Color[] DecodedColors = new Color[16]; for (int i = 0; i < 16; ++i) { if (FourCC == "DXT2" || FourCC == "DXT3" || FourCC == "DXT4" || FourCC == "DXT5") { int A = 255; #if EnableTransparency if (FourCC == "DXT2" || FourCC == "DXT3") { // Seems to be 8 maximum; so treat 8 as 255 and all other values as 3-bit alpha A = (int)((AlphaBlock >> (4 * i)) & 0xf); if (A >= 8) { A = 255; } else { A <<= 5; } } else { // Interpolated alpha int[] Alphas = new int[8]; Alphas[0] = (byte)((AlphaBlock >> 0) & 0xff); Alphas[1] = (byte)((AlphaBlock >> 8) & 0xff); if (Alphas[0] > Alphas[1]) { Alphas[2] = (Alphas[0] * 6 + Alphas[1] * 1 + 3) / 7; Alphas[3] = (Alphas[0] * 5 + Alphas[1] * 2 + 3) / 7; Alphas[4] = (Alphas[0] * 4 + Alphas[1] * 3 + 3) / 7; Alphas[5] = (Alphas[0] * 3 + Alphas[1] * 4 + 3) / 7; Alphas[6] = (Alphas[0] * 2 + Alphas[1] * 5 + 3) / 7; Alphas[7] = (Alphas[0] * 1 + Alphas[1] * 6 + 3) / 7; } else { Alphas[2] = (Alphas[0] * 4 + Alphas[1] * 1 + 2) / 5; Alphas[3] = (Alphas[0] * 3 + Alphas[1] * 2 + 2) / 5; Alphas[4] = (Alphas[0] * 2 + Alphas[1] * 3 + 2) / 5; Alphas[5] = (Alphas[0] * 1 + Alphas[1] * 4 + 2) / 5; Alphas[6] = 0; Alphas[7] = 255; } ulong AlphaMatrix = (AlphaBlock >> 16) & 0xffffffffffffL; A = Alphas[(AlphaMatrix >> (3 * i)) & 0x7]; } #endif DecodedColors[i] = Color.FromArgb(A, Colors[CompressedColor & 0x3]); } else { DecodedColors[i] = Colors[CompressedColor & 0x3]; } CompressedColor >>= 2; } return(DecodedColors); }