/// <summary>
        /// Decodes the given block
        /// </summary>
        /// <param name="inBlock">Block to decode</param>
        /// <param name="has1bitAlpha">Set if block contains DXT1 1-bit alpha (COMPRESSED_RGBA_S3TC_DXT1_EXT)</param>
        /// <param name="isDXT1">Set if block should be decoded as DXT1, else it will be decoded as DXT3/5</param>
        /// <returns></returns>
        private static byte[] DecodeColorBlock(DXT1Block inBlock, bool has1bitAlpha, bool isDXT1)
        {
            byte[] outData = new byte[(4 * 4) * 4];
            byte[,] colors = new byte[4, 4];

            UnpackRgb565(inBlock.Color0, out colors[0, 2], out colors[0, 1], out colors[0, 0]);
            UnpackRgb565(inBlock.Color1, out colors[1, 2], out colors[1, 1], out colors[1, 0]);
            colors[0, 3] = 255;
            colors[1, 3] = 255;

            if (isDXT1 && inBlock.Color0 <= inBlock.Color1)
            {
                colors[2, 0] = (byte)((colors[0, 0] + colors[1, 0]) / 2);
                colors[2, 1] = (byte)((colors[0, 1] + colors[1, 1]) / 2);
                colors[2, 2] = (byte)((colors[0, 2] + colors[1, 2]) / 2);
                colors[2, 3] = 255;

                colors[3, 0] = 0;
                colors[3, 1] = 0;
                colors[3, 2] = 0;
                colors[3, 3] = (byte)((has1bitAlpha && inBlock.Color0 <= inBlock.Color1) ? 0 : 0xFF);
            }
            else
            {
                colors[2, 0] = (byte)((2 * colors[0, 0] + colors[1, 0]) / 3);
                colors[2, 1] = (byte)((2 * colors[0, 1] + colors[1, 1]) / 3);
                colors[2, 2] = (byte)((2 * colors[0, 2] + colors[1, 2]) / 3);
                colors[2, 3] = 255;

                colors[3, 0] = (byte)((colors[0, 0] + 2 * colors[1, 0]) / 3);
                colors[3, 1] = (byte)((colors[0, 1] + 2 * colors[1, 1]) / 3);
                colors[3, 2] = (byte)((colors[0, 2] + 2 * colors[1, 2]) / 3);
                colors[3, 3] = 255;
            }

            for (int by = 0; by < 4; by++)
            {
                for (int bx = 0; bx < 4; bx++)
                {
                    byte code = inBlock.Bits[(by * 4) + bx];
                    for (int c = 0; c < 4; c++)
                    {
                        outData[(((by * 4) + bx) * 4) + c] = colors[code, c];
                    }
                }
            }

            return(outData);
        }
        public DXT3Block(EndianBinaryReader reader, DXTxBlockLayout blockLayout)
        {
            switch (blockLayout)
            {
            case DXTxBlockLayout.Normal:
                Alpha = reader.ReadUInt64();
                Color = new DXT1Block(reader, blockLayout);
                break;

            case DXTxBlockLayout.PSP:
                Color = new DXT1Block(reader, blockLayout);
                Alpha = reader.ReadUInt64();
                break;

            default:
                throw new Exception("Unknown block layout");
            }
        }
        public DXT5Block(EndianBinaryReader reader, DXTxBlockLayout blockLayout)
        {
            byte bits_5, bits_4, bits_3, bits_2, bits_1, bits_0;

            switch (blockLayout)
            {
            case DXTxBlockLayout.Normal:
                Alpha0 = reader.ReadByte();
                Alpha1 = reader.ReadByte();

                bits_5 = reader.ReadByte();
                bits_4 = reader.ReadByte();
                bits_3 = reader.ReadByte();
                bits_2 = reader.ReadByte();
                bits_1 = reader.ReadByte();
                bits_0 = reader.ReadByte();
                Bits   = DXTC.ExtractBits((((ulong)bits_0 << 40) | ((ulong)bits_1 << 32) | ((ulong)bits_2 << 24) | ((ulong)bits_3 << 16) | ((ulong)bits_4 << 8) | (ulong)bits_5), 3);

                Color = new DXT1Block(reader, blockLayout);
                break;

            case DXTxBlockLayout.PSP:
                Color  = new DXT1Block(reader, blockLayout);
                Alpha0 = reader.ReadByte();
                Alpha1 = reader.ReadByte();

                bits_5 = reader.ReadByte();
                bits_4 = reader.ReadByte();
                bits_3 = reader.ReadByte();
                bits_2 = reader.ReadByte();
                bits_1 = reader.ReadByte();
                bits_0 = reader.ReadByte();
                Bits   = DXTC.ExtractBits((((ulong)bits_0 << 40) | ((ulong)bits_1 << 32) | ((ulong)bits_2 << 24) | ((ulong)bits_3 << 16) | ((ulong)bits_4 << 8) | (ulong)bits_5), 3);
                break;

            default:
                throw new Exception("Unknown block layout");
            }
        }
        private static byte[] DecodeDXT1Block(EndianBinaryReader reader, PixelDataFormat inputFormat, DXTxBlockLayout blockLayout)
        {
            DXT1Block inBlock = new DXT1Block(reader, blockLayout);

            return(DecodeColorBlock(inBlock, (inputFormat & PixelDataFormat.MaskChannels) != PixelDataFormat.ChannelsRgb, true));
        }