/// <summary> /// Decodes a DXT1-compressed 4x4 block of texels using a prebuilt 4-color color table. /// </summary> /// <remarks>See https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC1 </remarks> static Color32[] DecodeDXT1TexelBlock(UnityBinaryReader r, Color[] colorTable) { Debug.Assert(colorTable.Length == 4); // Read pixel color indices. var colorIndices = new uint[16]; var colorIndexBytes = new byte[4]; r.Read(colorIndexBytes, 0, colorIndexBytes.Length); const uint bitsPerColorIndex = 2; for (uint rowIndex = 0; rowIndex < 4; rowIndex++) { var rowBaseColorIndexIndex = 4 * rowIndex; var rowBaseBitOffset = 8 * rowIndex; for (uint columnIndex = 0; columnIndex < 4; columnIndex++) { // Color indices are arranged from right to left. var bitOffset = rowBaseBitOffset + (bitsPerColorIndex * (3 - columnIndex)); colorIndices[rowBaseColorIndexIndex + columnIndex] = (uint)Utils.GetBits(bitOffset, bitsPerColorIndex, colorIndexBytes); } } // Calculate pixel colors. var colors = new Color32[16]; for (var i = 0; i < 16; i++) { colors[i] = colorTable[colorIndices[i]]; } return(colors); }
/// <summary> /// Decodes a DXT1-compressed 4x4 block of texels using a prebuilt 4-color color table. /// </summary> /// <remarks>See https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC1 </remarks> private static Color32[] DecodeDXT1TexelBlock(UnityBinaryReader reader, Color[] colorTable) { Debug.Assert(colorTable.Length == 4); // Read pixel color indices. //uint[] colorIndices = new uint[16]; //byte[] colorIndexBytes = new byte[4]; reader.Read(Dxt1colorIndexBytes, 0, Dxt1colorIndexBytes.Length); const uint bitsPerColorIndex = 2; uint rowIndex = 0; uint columnIndex = 0; uint rowBaseColorIndexIndex = 0; uint rowBaseBitOffset = 0; uint bitOffset = 0; for (rowIndex = 0; rowIndex < 4; rowIndex++) { rowBaseColorIndexIndex = 4 * rowIndex; rowBaseBitOffset = 8 * rowIndex; for (columnIndex = 0; columnIndex < 4; columnIndex++) { // Color indices are arranged from right to left. bitOffset = rowBaseBitOffset + (bitsPerColorIndex * (3 - columnIndex)); Dxt1colorIndices[rowBaseColorIndexIndex + columnIndex] = (uint)Utils.GetBits(bitOffset, bitsPerColorIndex, Dxt1colorIndexBytes); } } // Calculate pixel colors. //var colors = new Color32[16]; for (rowIndex = 0; rowIndex < 16; rowIndex++) { Dxt1Colors[rowIndex] = colorTable[Dxt1colorIndices[rowIndex]]; } return(Dxt1Colors); }
/// <summary> /// Decodes a DXT5-compressed 4x4 block of texels. /// </summary> /// <remarks>See https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC3 </remarks> private static Color32[] DecodeDXT5TexelBlock(UnityBinaryReader reader) { // Create the alpha table. var alphaTable = new float[8]; alphaTable[0] = reader.ReadByte(); alphaTable[1] = reader.ReadByte(); if (alphaTable[0] > alphaTable[1]) { for (int i = 0; i < 6; i++) { alphaTable[2 + i] = Mathf.Lerp(alphaTable[0], alphaTable[1], (float)(1 + i) / 7); } } else { for (int i = 0; i < 4; i++) { alphaTable[2 + i] = Mathf.Lerp(alphaTable[0], alphaTable[1], (float)(1 + i) / 5); } alphaTable[6] = 0; alphaTable[7] = 255; } // Read pixel alpha indices. var alphaIndices = new uint[16]; var alphaIndexBytesRow0 = new byte[3]; reader.Read(alphaIndexBytesRow0, 0, alphaIndexBytesRow0.Length); Array.Reverse(alphaIndexBytesRow0); // Take care of little-endianness. var alphaIndexBytesRow1 = new byte[3]; reader.Read(alphaIndexBytesRow1, 0, alphaIndexBytesRow1.Length); Array.Reverse(alphaIndexBytesRow1); // Take care of little-endianness. const uint bitsPerAlphaIndex = 3; alphaIndices[0] = (uint)Utils.GetBits(21, bitsPerAlphaIndex, alphaIndexBytesRow0); alphaIndices[1] = (uint)Utils.GetBits(18, bitsPerAlphaIndex, alphaIndexBytesRow0); alphaIndices[2] = (uint)Utils.GetBits(15, bitsPerAlphaIndex, alphaIndexBytesRow0); alphaIndices[3] = (uint)Utils.GetBits(12, bitsPerAlphaIndex, alphaIndexBytesRow0); alphaIndices[4] = (uint)Utils.GetBits(9, bitsPerAlphaIndex, alphaIndexBytesRow0); alphaIndices[5] = (uint)Utils.GetBits(6, bitsPerAlphaIndex, alphaIndexBytesRow0); alphaIndices[6] = (uint)Utils.GetBits(3, bitsPerAlphaIndex, alphaIndexBytesRow0); alphaIndices[7] = (uint)Utils.GetBits(0, bitsPerAlphaIndex, alphaIndexBytesRow0); alphaIndices[8] = (uint)Utils.GetBits(21, bitsPerAlphaIndex, alphaIndexBytesRow1); alphaIndices[9] = (uint)Utils.GetBits(18, bitsPerAlphaIndex, alphaIndexBytesRow1); alphaIndices[10] = (uint)Utils.GetBits(15, bitsPerAlphaIndex, alphaIndexBytesRow1); alphaIndices[11] = (uint)Utils.GetBits(12, bitsPerAlphaIndex, alphaIndexBytesRow1); alphaIndices[12] = (uint)Utils.GetBits(9, bitsPerAlphaIndex, alphaIndexBytesRow1); alphaIndices[13] = (uint)Utils.GetBits(6, bitsPerAlphaIndex, alphaIndexBytesRow1); alphaIndices[14] = (uint)Utils.GetBits(3, bitsPerAlphaIndex, alphaIndexBytesRow1); alphaIndices[15] = (uint)Utils.GetBits(0, bitsPerAlphaIndex, alphaIndexBytesRow1); // Create the color table. var colorTable = new Color[4]; colorTable[0] = ColorUtils.R5G6B5ToColor(reader.ReadLEUInt16()); colorTable[1] = ColorUtils.R5G6B5ToColor(reader.ReadLEUInt16()); colorTable[2] = Color.Lerp(colorTable[0], colorTable[1], 1.0f / 3); colorTable[3] = Color.Lerp(colorTable[0], colorTable[1], 2.0f / 3); // Calculate pixel colors. var colors = DecodeDXT1TexelBlock(reader, colorTable); for (int i = 0; i < 16; i++) { colors[i].a = (byte)Mathf.Round(alphaTable[alphaIndices[i]]); } return(colors); }
/// <summary> /// Decodes a DXT5-compressed 4x4 block of texels. /// </summary> /// <remarks>See https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC3 </remarks> private static Color32[] DecodeDXT5TexelBlock(UnityBinaryReader reader) { // Create the alpha table. var alphaTable = new float[8]; alphaTable[0] = reader.ReadByte(); alphaTable[1] = reader.ReadByte(); if(alphaTable[0] > alphaTable[1]) { for(int i = 0; i < 6; i++) { alphaTable[2 + i] = Mathf.Lerp(alphaTable[0], alphaTable[1], (float)(1 + i) / 7); } } else { for(int i = 0; i < 4; i++) { alphaTable[2 + i] = Mathf.Lerp(alphaTable[0], alphaTable[1], (float)(1 + i) / 5); } alphaTable[6] = 0; alphaTable[7] = 255; } // Read pixel alpha indices. var alphaIndices = new uint[16]; var alphaIndexBytesRow0 = new byte[3]; reader.Read(alphaIndexBytesRow0, 0, alphaIndexBytesRow0.Length); Array.Reverse(alphaIndexBytesRow0); // Take care of little-endianness. var alphaIndexBytesRow1 = new byte[3]; reader.Read(alphaIndexBytesRow1, 0, alphaIndexBytesRow1.Length); Array.Reverse(alphaIndexBytesRow1); // Take care of little-endianness. const uint bitsPerAlphaIndex = 3; alphaIndices[0] = (uint)Utils.GetBits(21, bitsPerAlphaIndex, alphaIndexBytesRow0); alphaIndices[1] = (uint)Utils.GetBits(18, bitsPerAlphaIndex, alphaIndexBytesRow0); alphaIndices[2] = (uint)Utils.GetBits(15, bitsPerAlphaIndex, alphaIndexBytesRow0); alphaIndices[3] = (uint)Utils.GetBits(12, bitsPerAlphaIndex, alphaIndexBytesRow0); alphaIndices[4] = (uint)Utils.GetBits(9, bitsPerAlphaIndex, alphaIndexBytesRow0); alphaIndices[5] = (uint)Utils.GetBits(6, bitsPerAlphaIndex, alphaIndexBytesRow0); alphaIndices[6] = (uint)Utils.GetBits(3, bitsPerAlphaIndex, alphaIndexBytesRow0); alphaIndices[7] = (uint)Utils.GetBits(0, bitsPerAlphaIndex, alphaIndexBytesRow0); alphaIndices[8] = (uint)Utils.GetBits(21, bitsPerAlphaIndex, alphaIndexBytesRow1); alphaIndices[9] = (uint)Utils.GetBits(18, bitsPerAlphaIndex, alphaIndexBytesRow1); alphaIndices[10] = (uint)Utils.GetBits(15, bitsPerAlphaIndex, alphaIndexBytesRow1); alphaIndices[11] = (uint)Utils.GetBits(12, bitsPerAlphaIndex, alphaIndexBytesRow1); alphaIndices[12] = (uint)Utils.GetBits(9, bitsPerAlphaIndex, alphaIndexBytesRow1); alphaIndices[13] = (uint)Utils.GetBits(6, bitsPerAlphaIndex, alphaIndexBytesRow1); alphaIndices[14] = (uint)Utils.GetBits(3, bitsPerAlphaIndex, alphaIndexBytesRow1); alphaIndices[15] = (uint)Utils.GetBits(0, bitsPerAlphaIndex, alphaIndexBytesRow1); // Create the color table. var colorTable = new Color[4]; colorTable[0] = ColorUtils.R5G6B5ToColor(reader.ReadLEUInt16()); colorTable[1] = ColorUtils.R5G6B5ToColor(reader.ReadLEUInt16()); colorTable[2] = Color.Lerp(colorTable[0], colorTable[1], 1.0f / 3); colorTable[3] = Color.Lerp(colorTable[0], colorTable[1], 2.0f / 3); // Calculate pixel colors. var colors = DecodeDXT1TexelBlock(reader, colorTable); for(int i = 0; i < 16; i++) { colors[i].a = (byte)Mathf.Round(alphaTable[alphaIndices[i]]); } return colors; }
/// <summary> /// Decodes a DXT1-compressed 4x4 block of texels using a prebuilt 4-color color table. /// </summary> /// <remarks>See https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC1 </remarks> private static Color32[] DecodeDXT1TexelBlock(UnityBinaryReader reader, Color[] colorTable) { Debug.Assert(colorTable.Length == 4); // Read pixel color indices. var colorIndices = new uint[16]; var colorIndexBytes = new byte[4]; reader.Read(colorIndexBytes, 0, colorIndexBytes.Length); const uint bitsPerColorIndex = 2; for(uint rowIndex = 0; rowIndex < 4; rowIndex++) { var rowBaseColorIndexIndex = 4 * rowIndex; var rowBaseBitOffset = 8 * rowIndex; for(uint columnIndex = 0; columnIndex < 4; columnIndex++) { // Color indices are arranged from right to left. var bitOffset = rowBaseBitOffset + (bitsPerColorIndex * (3 - columnIndex)); colorIndices[rowBaseColorIndexIndex + columnIndex] = (uint)Utils.GetBits(bitOffset, bitsPerColorIndex, colorIndexBytes); } } // Calculate pixel colors. var colors = new Color32[16]; for(int i = 0; i < 16; i++) { colors[i] = colorTable[colorIndices[i]]; } return colors; }