/// <summary>
        /// Turn raw BGRA8888 bytes to a Color array that can be used in a Texture2D.
        /// </summary>
        /// <param name="data">Raw image byte data</param>
        /// <param name="width">Expected width of the image</param>
        /// <param name="height">Expected height of the image</param>
        /// <returns>Pixel color data</returns>
        public static Color[] DecompressBGRA8888(Stream data, ushort width, ushort height)
        {
            Color[] texture2DColors = new Color[width * height];

            bool exceededArray = false;

            for (int row = 0; row < height; row++)
            {
                for (int col = 0; col < width; col++)
                {
                    byte blue  = DataParser.ReadByte(data);
                    byte green = DataParser.ReadByte(data);
                    byte red   = DataParser.ReadByte(data);
                    byte alpha = DataParser.ReadByte(data);

                    int flattenedIndex = row * width + col;
                    if (flattenedIndex < texture2DColors.Length)
                    {
                        texture2DColors[flattenedIndex] = new Color(((float)red) / byte.MaxValue, ((float)green) / byte.MaxValue, ((float)blue) / byte.MaxValue, ((float)alpha) / byte.MaxValue);
                    }
                    else
                    {
                        Debug.LogError("BGRA8888: Exceeded expected texture size");
                        exceededArray = true;
                        break;
                    }
                }

                if (exceededArray)
                {
                    break;
                }
            }

            return(texture2DColors);
        }
示例#2
0
        public const int DDS_DX10 = 808540228; //From "DX10"

        public static Texture2D LoadDDSFile(Stream data)
        {
            Texture2D texture = null;

            Color[]       imageColors = null;
            DDS_HEADER    header      = new DDS_HEADER();
            DDS_HEADER_10 header_10   = new DDS_HEADER_10();

            int magic = DataParser.ReadInt(data);

            if (magic == DDS_)
            {
                header.dwSize              = DataParser.ReadInt(data);          //0 + 4 = 4
                header.dwFlags             = (DWFlags)DataParser.ReadInt(data); //4 + 4 = 8
                header.dwHeight            = DataParser.ReadInt(data);          //8 + 4 = 12
                header.dwWidth             = DataParser.ReadInt(data);          //12 + 4 = 16
                header.dwPitchOrLinearSize = DataParser.ReadInt(data);          //16 + 4 = 20
                header.dwDepth             = DataParser.ReadInt(data);          //20 + 4 = 24
                header.dwMipMapCount       = DataParser.ReadInt(data);          //24 + 4 = 28
                header.dwReserved1         = new int[11];                       //28 + 44 = 72
                for (int i = 0; i < header.dwReserved1.Length; i++)
                {
                    header.dwReserved1[i] = DataParser.ReadInt(data);
                }

                header.ddspf.dwSize        = DataParser.ReadInt(data);                      //72 + 4 = 76
                header.ddspf.dwFlags       = (PIXELFORMAT_DWFlags)DataParser.ReadInt(data); //76 + 4 = 80
                header.ddspf.dwFourCC      = DataParser.ReadInt(data);                      //80 + 4 = 84
                header.ddspf.dwRGBBitCount = DataParser.ReadInt(data);                      //84 + 4 = 88
                header.ddspf.dwRBitMask    = DataParser.ReadInt(data);                      //88 + 4 = 92
                header.ddspf.dwGBitMask    = DataParser.ReadInt(data);                      //92 + 4 = 96
                header.ddspf.dwBBitMask    = DataParser.ReadInt(data);                      //96 + 4 = 100
                header.ddspf.dwABitMask    = DataParser.ReadInt(data);                      //100 + 4 = 104

                header.dwCaps      = DataParser.ReadInt(data);                              //104 + 4 = 108
                header.dwCaps2     = DataParser.ReadInt(data);                              //108 + 4 = 112
                header.dwCaps3     = DataParser.ReadInt(data);                              //112 + 4 = 116
                header.dwCaps4     = DataParser.ReadInt(data);                              //116 + 4 = 120
                header.dwReserved2 = DataParser.ReadInt(data);                              //120 + 4 = 124

                bool isCompressed = (header.ddspf.dwFlags & PIXELFORMAT_DWFlags.DDPF_FOURCC) != 0;
                if (isCompressed && header.ddspf.dwFourCC == DDS_DX10)
                {
                    Debug.Log(nameof(DDSLoader) + ": Reading extra header");
                    header_10.dxgiFormat        = (DXGI_FORMAT)DataParser.ReadInt(data);
                    header_10.resourceDimension = (D3D10_RESOURCE_DIMENSION)DataParser.ReadInt(data);
                    header_10.miscFlag          = DataParser.ReadUInt(data);
                    header_10.arraySize         = DataParser.ReadUInt(data);
                    header_10.miscFlags2        = DataParser.ReadUInt(data);
                }

                imageColors = Texture2DHelpers.DecompressRawBytes(data, (ushort)header.dwWidth, (ushort)header.dwHeight, GetDDSFormat(header));
                Texture2DHelpers.FlipVertical(imageColors, (ushort)header.dwWidth, (ushort)header.dwHeight);
            }
            else
            {
                Debug.LogError(nameof(DDSLoader) + ": Invalid DDS magic, expected " + DDS_ + " got " + magic);
            }

            if (imageColors != null)
            {
                texture = new Texture2D(header.dwWidth, header.dwHeight);
                if (imageColors != null)
                {
                    texture.SetPixels(imageColors);
                }
                texture.Apply();
            }

            return(texture);
        }
        /// <summary>
        /// Turn raw DXT5 bytes to a Color array that can be used in a Texture2D.
        /// </summary>
        /// <param name="data">Raw image byte data</param>
        /// <param name="width">Expected width of the image</param>
        /// <param name="height">Expected height of the image</param>
        /// <returns>Pixel color data</returns>
        public static Color[] DecompressDXT5(Stream data, ushort width, ushort height)
        {
            Color[] texture2DColors = new Color[width * height];

            for (int row = 0; row < height; row += 4)
            {
                for (int col = 0; col < width; col += 4)
                {
                    #region Alpha Information
                    byte alpha0Data = 0;
                    byte alpha1Data = 0;
                    uint alphamask  = 0;

                    alpha0Data = DataParser.ReadByte(data);
                    alpha1Data = DataParser.ReadByte(data);
                    byte[] amdata = new byte[6];
                    data.Read(amdata, 0, amdata.Length);
                    alphamask = BitConverter.ToUInt32(amdata, 0);

                    float[] alphaPalette = new float[]
                    {
                        alpha0Data / 255f,
                        alpha1Data / 255f,
                        ((6 * alpha0Data + 1 * alpha1Data + 3) / 7) / 255f,
                        ((5 * alpha0Data + 2 * alpha1Data + 3) / 7) / 255f,
                        ((4 * alpha0Data + 3 * alpha1Data + 3) / 7) / 255f,
                        ((3 * alpha0Data + 4 * alpha1Data + 3) / 7) / 255f,
                        ((2 * alpha0Data + 5 * alpha1Data + 3) / 7) / 255f,
                        ((1 * alpha0Data + 6 * alpha1Data + 3) / 7) / 255f
                    };

                    if (alpha0Data <= alpha1Data)
                    {
                        alphaPalette[2] = (4 * alpha0Data + 1 * alpha1Data + 2) / 5;
                        alphaPalette[3] = (3 * alpha0Data + 2 * alpha1Data + 2) / 5;
                        alphaPalette[4] = (2 * alpha0Data + 3 * alpha1Data + 2) / 5;
                        alphaPalette[5] = (1 * alpha0Data + 4 * alpha1Data + 2) / 5;
                        alphaPalette[6] = 0;
                        alphaPalette[7] = 1;
                    }
                    #endregion

                    #region Color Information
                    ushort color0Data = 0;
                    ushort color1Data = 0;
                    uint   bitmask    = 0;

                    color0Data = DataParser.ReadUShort(data);
                    color1Data = DataParser.ReadUShort(data);
                    bitmask    = DataParser.ReadUInt(data);

                    int[] colors0 = new int[] { ((color0Data >> 11) & 0x1F) << 3, ((color0Data >> 5) & 0x3F) << 2, (color0Data & 0x1F) << 3 };
                    int[] colors1 = new int[] { ((color1Data >> 11) & 0x1F) << 3, ((color1Data >> 5) & 0x3F) << 2, (color1Data & 0x1F) << 3 };

                    Color[] colorPalette = new Color[]
                    {
                        new Color(colors0[0] / 255f, colors0[1] / 255f, colors0[2] / 255f),
                        new Color(colors1[0] / 255f, colors1[1] / 255f, colors1[2] / 255f),
                        new Color(((colors0[0] * 2 + colors1[0] + 1) / 3) / 255f, ((colors0[1] * 2 + colors1[1] + 1) / 3) / 255f, ((colors0[2] * 2 + colors1[2] + 1) / 3) / 255f),
                        new Color(((colors1[0] * 2 + colors0[0] + 1) / 3) / 255f, ((colors1[1] * 2 + colors0[1] + 1) / 3) / 255f, ((colors1[2] * 2 + colors0[2] + 1) / 3) / 255f)
                    };
                    #endregion

                    #region Place All Information
                    int  blockIndex = 0;
                    uint alphaBlockIndex1 = alphamask & 0x07, alphaBlockIndex2 = alphamask & 0x38;
                    for (int blockY = 0; blockY < 4; blockY++)
                    {
                        for (int blockX = 0; blockX < 4; blockX++)
                        {
                            Color colorInBlock = colorPalette[(bitmask & (0x03 << blockIndex * 2)) >> blockIndex * 2];
                            if (blockY < 2)
                            {
                                colorInBlock.a = alphaPalette[alphaBlockIndex1 & 0x07];
                            }
                            else
                            {
                                colorInBlock.a = alphaPalette[alphaBlockIndex2 & 0x07];
                            }
                            texture2DColors[((row * width) + col) + ((blockY * width) + blockX)] = colorInBlock;
                            blockIndex++;
                        }
                        alphaBlockIndex1 >>= 3;
                        alphaBlockIndex2 >>= 3;
                    }
                    #endregion
                }
            }

            return(texture2DColors.ToArray());
        }