Beispiel #1
0
        /// <summary>
        /// Builds a 4-color color table for a DXT1-compressed 4x4 block of texels and then decodes the texels.
        /// </summary>
        /// <remarks>See https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC1 </remarks>
        static Color32[] DecodeDXT1TexelBlock(UnityBinaryReader r, bool containsAlpha)
        {
            // Create the color table.
            var colorTable = new Color[4];

            colorTable[0] = ColorEx.B565ToColor(r.ReadLEUInt16());
            colorTable[1] = ColorEx.B565ToColor(r.ReadLEUInt16());
            if (!containsAlpha)
            {
                colorTable[2] = Color.Lerp(colorTable[0], colorTable[1], 1.0f / 3);
                colorTable[3] = Color.Lerp(colorTable[0], colorTable[1], 2.0f / 3);
            }
            else
            {
                colorTable[2] = Color.Lerp(colorTable[0], colorTable[1], 1.0f / 2);
                colorTable[3] = new Color(0, 0, 0, 0);
            }
            // Calculate pixel colors.
            return(DecodeDXT1TexelBlock(r, colorTable));
        }
Beispiel #2
0
        /// <summary>
        /// Decodes a DXT3-compressed 4x4 block of texels.
        /// </summary>
        /// <remarks>See https://msdn.microsoft.com/en-us/library/windows/desktop/bb694531(v=vs.85).aspx#BC2 </remarks>
        static Color32[] DecodeDXT3TexelBlock(UnityBinaryReader r)
        {
            // Read compressed pixel alphas.
            var compressedAlphas = new byte[16];

            for (var rowIndex = 0; rowIndex < 4; rowIndex++)
            {
                var compressedAlphaRow = r.ReadLEUInt16();
                for (var columnIndex = 0; columnIndex < 4; columnIndex++)
                {
                    // Each compressed alpha is 4 bits.
                    compressedAlphas[(4 * rowIndex) + columnIndex] = (byte)((compressedAlphaRow >> (columnIndex * 4)) & 0xF);
                }
            }
            // Calculate pixel alphas.
            var alphas = new byte[16];

            for (var i = 0; i < 16; i++)
            {
                var alphaPercent = (float)compressedAlphas[i] / 15;
                alphas[i] = (byte)Mathf.RoundToInt(alphaPercent * 255);
            }
            // Create the color table.
            var colorTable = new Color[4];

            colorTable[0] = ColorEx.B565ToColor(r.ReadLEUInt16());
            colorTable[1] = ColorEx.B565ToColor(r.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(r, colorTable);

            for (var i = 0; i < 16; i++)
            {
                colors[i].a = alphas[i];
            }
            return(colors);
        }
Beispiel #3
0
        /// <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>
        static Color32[] DecodeDXT5TexelBlock(UnityBinaryReader r)
        {
            // Create the alpha table.
            var alphaTable = new float[8];

            alphaTable[0] = r.ReadByte();
            alphaTable[1] = r.ReadByte();
            if (alphaTable[0] > alphaTable[1])
            {
                for (var i = 0; i < 6; i++)
                {
                    alphaTable[2 + i] = Mathf.Lerp(alphaTable[0], alphaTable[1], (float)(1 + i) / 7);
                }
            }
            else
            {
                for (var 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];

            r.Read(alphaIndexBytesRow0, 0, alphaIndexBytesRow0.Length);
            Array.Reverse(alphaIndexBytesRow0); // Take care of little-endianness.
            var alphaIndexBytesRow1 = new byte[3];

            r.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] = ColorEx.B565ToColor(r.ReadLEUInt16());
            colorTable[1] = ColorEx.B565ToColor(r.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(r, colorTable);

            for (var i = 0; i < 16; i++)
            {
                colors[i].a = (byte)Mathf.Round(alphaTable[alphaIndices[i]]);
            }
            return(colors);
        }