コード例 #1
0
ファイル: DDSLoader.cs プロジェクト: tungcheng/UnityHelpers
        public static Texture2DHelpers.TextureFormat GetDDSFormat(DDS_HEADER header)
        {
            Texture2DHelpers.TextureFormat format;

            bool isCompressed = (header.ddspf.dwFlags & PIXELFORMAT_DWFlags.DDPF_FOURCC) != 0;

            if (isCompressed)
            {
                if (header.ddspf.dwFourCC == DDS_DXT5)
                {
                    format = Texture2DHelpers.TextureFormat.DXT5;
                }
                else if (header.ddspf.dwFourCC == DDS_DXT3)
                {
                    format = Texture2DHelpers.TextureFormat.DXT3;
                }
                else
                {
                    format = Texture2DHelpers.TextureFormat.DXT1;
                }
            }
            else if ((header.ddspf.dwFlags & PIXELFORMAT_DWFlags.DDPF_ALPHA) != 0 || (header.ddspf.dwFlags & PIXELFORMAT_DWFlags.DDPF_ALPHAPIXELS) != 0)
            {
                format = Texture2DHelpers.TextureFormat.BGRA8888;
            }
            else
            {
                format = Texture2DHelpers.TextureFormat.BGR888;
            }

            return(format);
        }
コード例 #2
0
ファイル: ImageFormats.cs プロジェクト: LazyBone152/XV2-Tools
        /// <summary>
        /// Gets image format of image file.
        /// </summary>
        /// <param name="imagePath">Path to image file.</param>
        /// <returns>Format of image.</returns>
        public static Format ParseFormat(string imagePath, ref DDS_HEADER header)
        {
            SupportedExtensions ext = ParseExtension(imagePath);

            using (FileStream fs = new FileStream(imagePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                return(ParseFormat(fs, ext, ref header));
        }
コード例 #3
0
        static bool?IsV8U8(Stream stream)
        {
            stream.Seek(0, SeekOrigin.Begin);
            using (BinaryReader r = new BinaryReader(stream, Encoding.Default, true))
            {
                int dwMagic = r.ReadInt32();
                if (dwMagic != 0x20534444)
                {
                    return(null);
                }

                DDS_HEADER header = new DDS_HEADER();
                Read_DDS_HEADER(header, r);

                if (((header.ddspf.dwFlags & 0x00000004) != 0) && (header.ddspf.dwFourCC == 0x30315844 /*DX10*/))
                {
                    throw new Exception("DX10 not supported yet!");
                }
                return(header.ddspf.dwRGBBitCount == 0x10 &&
                       header.ddspf.dwRBitMask == 0xFF &&
                       header.ddspf.dwGBitMask == 0xFF00 &&
                       header.ddspf.dwBBitMask == 0x00 &&
                       header.ddspf.dwABitMask == 0x00);
            }
        }
コード例 #4
0
        private static bool WriteV8U8ToStream(IEnumerable <MipMap> mipmaps, Stream destination, int width, int height, int Mips, bool DisposeStream)
        {
            DDS_HEADER header = Build_V8U8_DDS_Header(Mips, height, width);

            try
            {
                using (BinaryWriter writer = new BinaryWriter(destination, Encoding.Default, !DisposeStream))
                {
                    // KFreon: Get and write header
                    Write_V8U8_DDS_Header(header, writer);

                    foreach (MipMap mip in mipmaps)
                    {
                        foreach (sbyte byt in mip.data)
                        {
                            writer.Write(byt);
                        }
                    }
                }

                return(true);
            }
            catch (IOException e)
            {
                Debug.WriteLine("Error writing to file: " + e.Message);
            }
            return(false);
        }
コード例 #5
0
        static SurfaceFormat GetSurfaceFormat(ref DDS_HEADER header)
        {
            //Compressed
            switch (header.ddspf.dwFourCC)
            {
            case FourCC.DXT1:
                return(SurfaceFormat.Dxt1);

            case FourCC.DXT3:
                return(SurfaceFormat.Dxt3);

            case FourCC.DXT5:
                return(SurfaceFormat.Dxt5);
            }
            //Uncompressed 16-bit formats
            if (header.ddspf.dwFlags == 0x41 &&
                header.ddspf.dwRGBBitCount == 0x10 &&
                header.ddspf.dwFourCC == 0 &&
                header.ddspf.dwRBitMask == 0x7c00 &&
                header.ddspf.dwGBitMask == 0x3e0 &&
                header.ddspf.dwBBitMask == 0x1f &&
                header.ddspf.dwABitMask == 0x8000)
            {
                return(SurfaceFormat.Bgra5551);
            }

            if (header.ddspf.dwFlags == 0x40 &&
                header.ddspf.dwRGBBitCount == 0x10 &&
                header.ddspf.dwFourCC == 0 &&
                header.ddspf.dwRBitMask == 0xf800 &&
                header.ddspf.dwGBitMask == 0x7e0 &&
                header.ddspf.dwBBitMask == 0x1f &&
                header.ddspf.dwABitMask == 0)
            {
                return(SurfaceFormat.Bgr565);
            }

            if (header.ddspf.dwFlags == 0x41 &&
                header.ddspf.dwRGBBitCount == 0x10 &&
                header.ddspf.dwFourCC == 0 &&
                header.ddspf.dwRBitMask == 0xf00 &&
                header.ddspf.dwGBitMask == 240 &&
                header.ddspf.dwBBitMask == 15 &&
                header.ddspf.dwABitMask == 0xf000)
            {
                return(SurfaceFormat.Bgra4444);
            }
            //Uncompressed 32-bit and 24-bit formats
            if ((header.ddspf.dwFlags == 0x41 || header.ddspf.dwFlags == 0x40) &&
                (header.ddspf.dwRGBBitCount == 0x20 || header.ddspf.dwRGBBitCount == 0x18) &&
                header.ddspf.dwFourCC == 0 &&
                header.ddspf.dwABitMask != 0xc0000000)     //Exclude A2B10G10R10
            {
                return(SurfaceFormat.Color);
            }
            throw new NotSupportedException("Pixel Format (FourCC " + header.ddspf.dwFourCC.ToString() + ")");
        }
コード例 #6
0
ファイル: ImageFormats.cs プロジェクト: LazyBone152/XV2-Tools
        /// <summary>
        /// Gets image format from stream containing image file, along with extension of image file.
        /// </summary>
        /// <param name="imgData">Stream containing entire image file. NOT just pixels.</param>
        /// <param name="extension">Extension of image file.</param>
        /// <returns>Format of image.</returns>
        public static Format ParseFormat(Stream imgData, string extension, ref DDS_HEADER header)
        {
            SupportedExtensions ext = SupportedExtensions.UNKNOWN;

            // KFreon: Attempt to determine from data
            if (extension == null)
            {
                // KFreon: Save position and go back to start
                long originalPos = imgData.Position;
                imgData.Seek(0, SeekOrigin.Begin);

                char l1 = (char)imgData.ReadByte();
                char l2 = (char)imgData.ReadByte();
                char l3 = (char)imgData.ReadByte();
                char l4 = (char)imgData.ReadByte();

                // BMP
                if (l1 == 'B' && l2 == 'M')
                {
                    ext = SupportedExtensions.BMP;
                }

                // PNG
                if (l1 == 137 && l2 == 'P' && l3 == 'N' && l4 == 'G')
                {
                    ext = SupportedExtensions.PNG;
                }

                // JPG
                if (l1 == 0xFF && l2 == 0xD8 && l3 == 0xFF)
                {
                    ext = SupportedExtensions.JPG;
                }

                // DDS
                if (l1 == 'D' && l2 == 'D' && l3 == 'S')
                {
                    ext = SupportedExtensions.DDS;
                }

                // KFreon: Reset stream position
                imgData.Seek(originalPos, SeekOrigin.Begin);
            }
            else
            {
                ext = ParseExtension(extension);
            }

            if (ext == SupportedExtensions.UNKNOWN)
            {
                return(new Format());
            }

            return(ParseFormat(imgData, ext, ref header));
        }
コード例 #7
0
ファイル: DDS_Metadata.cs プロジェクト: TarekJor/Wolven-kit
        public DDSMetadata(DDS_HEADER ddsheader)
        {
            var mask = DDSUtils.DDSCAPS2_CUBEMAP_ALL_FACES & DDSUtils.DDSCAPS2_CUBEMAP;

            if ((ddsheader.dwCaps2 & mask) != 0)
            {
            }

            bool iscubemap = (ddsheader.dwCaps2 & mask) != 0;


            Width     = ddsheader.dwWidth;
            Height    = ddsheader.dwHeight;
            Mipscount = ddsheader.dwMipMapCount;

            switch (ddsheader.ddspf.dwFourCC)
            {
            case 0x31545844:        //DXT1
                Format = EFormat.BC1_UNORM;
                break;

            case 0x33545844:        //DXT3
                Format = EFormat.BC2_UNORM;
                break;

            case 0x35545844:        //DXT5
                Format = EFormat.BC3_UNORM;
                break;

            case 0x55344342:        //BC4U
                Format = EFormat.BC4_UNORM;
                break;

            case 0x55354342:        //BC5U
                Format = EFormat.BC5_UNORM;
                break;

            //case
            //    Format = EFormat.R8G8B8A8_UNORM:
            //    SetPixelmask(DDSPF_A8R8G8B8, ref ddspf); break;
            //case
            //    Format = EFormat.BC7_UNORM ;          //TODO: dxt10 is currently unsupported
            //    dxt10 = true; break;
            default:
                Format = EFormat.R8G8B8A8_UNORM;
                break;
            }


            Bpp        = 16;                                //TODO: in vanilla this is always 16 ???
            Iscubemap  = iscubemap;
            Slicecount = iscubemap ? (uint)6 : (uint)0;     //TODO: does not account for texarrays
            Dx10       = false;
        }
コード例 #8
0
        private void LoadImage(Stream stream)
        {
            stream.Seek(0, SeekOrigin.Begin);
            BinaryReader r       = new BinaryReader(stream);
            int          dwMagic = r.ReadInt32();

            if (dwMagic != 0x20534444)
            {
                throw new Exception("This is not a DDS! Magic number wrong.");
            }

            DDS_HEADER header = new DDS_HEADER();

            Read_DDS_HEADER(header, r);

            if (((header.ddspf.dwFlags & 0x00000004) != 0) && (header.ddspf.dwFourCC == 0x30315844 /*DX10*/))
            {
                throw new Exception("DX10 not supported yet!");
            }

            if (header.ddspf.dwFourCC != 0)
            {
                throw new InvalidDataException("DDS not V8U8.");
            }

            int mipMapCount = 1;

            if ((header.dwFlags & 0x00020000) != 0)
            {
                mipMapCount = header.dwMipMapCount;
            }

            int w = 0;
            int h = 0;

            double bytePerPixel = 2;

            MipMaps = new MipMap[mipMapCount];

            // KFreon: Get mips
            for (int i = 0; i < mipMapCount; i++)
            {
                w = (int)(header.dwWidth / Math.Pow(2, i));
                h = (int)(header.dwHeight / Math.Pow(2, i));

                int mipMapBytes = (int)(w * h * bytePerPixel);
                MipMaps[i] = new MipMap(r.ReadBytes(mipMapBytes), w, h);
            }

            Width  = header.dwWidth;
            Height = header.dwHeight;
        }
コード例 #9
0
        static Texture2D GetTexture2D(ref DDS_HEADER header, BinaryReader reader)
        {
            SurfaceFormat fmt;
            int           w, h;
            var           surface = LoadSurface(ref header, reader, out fmt, out w, out h);
            var           tex     = new Texture2D(w, h, surface.Length > 1, fmt);

            for (int i = 0; i < surface.Length; i++)
            {
                tex.SetData(i, null, surface[i], 0, surface[i].Length);
            }
            return(tex);
        }
コード例 #10
0
        private static ShaderResourceView CreateTextureFromDDS(Device device, DeviceContext context, byte[] data, out bool isCubeMap)
        {
            // Validate DDS file in memory
            DDS_HEADER header = new DDS_HEADER();

            int ddsHeaderSize   = Marshal.SizeOf(header);
            int ddspfSize       = Marshal.SizeOf(new DDS_PIXELFORMAT());
            int ddsHeader10Size = Marshal.SizeOf(new DDS_HEADER_DXT10());

            if (data.Length < (sizeof(uint) + ddsHeaderSize))
            {
                throw new Exception();
            }

            //first is magic number
            int dwMagicNumber = BitConverter.ToInt32(data, 0);

            if (dwMagicNumber != DDS_MAGIC)
            {
                throw new Exception();
            }

            header = ByteArrayToStructure <DDS_HEADER>(data, 4, ddsHeaderSize);

            // Verify header to validate DDS file
            if (header.size != ddsHeaderSize ||
                header.ddspf.size != ddspfSize)
            {
                throw new Exception();
            }

            // Check for DX10 extension
            bool bDXT10Header = false;

            if (((header.ddspf.flags & DDS_FOURCC) > 0) && (MAKEFOURCC('D', 'X', '1', '0') == header.ddspf.fourCC))
            {
                // Must be long enough for both headers and magic value
                if (data.Length < (ddsHeaderSize + 4 + ddsHeader10Size))
                {
                    throw new Exception();
                }

                bDXT10Header = true;
            }

            int offset = 4 + ddsHeaderSize + (bDXT10Header ? ddsHeader10Size : 0);

            return(InitTextureFromData(device, context, header, null, data, offset, 0, out isCubeMap));
        }
コード例 #11
0
        static TextureCube GetTextureCube(ref DDS_HEADER header, BinaryReader reader)
        {
            SurfaceFormat fmt;
            int           w, h;
            var           sfc = LoadSurface(ref header, reader, out fmt, out w, out h);
            var           tex = new TextureCube(w, sfc.Length > 1, fmt);

            //Positive X
            for (int i = 0; i < sfc.Length; i++)
            {
                tex.SetData(CubeMapFace.PositiveX, 0, null, sfc[i], 0, sfc[i].Length);
            }
            //Negative
            sfc = LoadSurface(ref header, reader, out fmt, out w, out h);
            for (int i = 0; i < sfc.Length; i++)
            {
                tex.SetData(CubeMapFace.NegativeX, 0, null, sfc[i], 0, sfc[i].Length);
            }
            //Positive Y
            sfc = LoadSurface(ref header, reader, out fmt, out w, out h);
            for (int i = 0; i < sfc.Length; i++)
            {
                tex.SetData(CubeMapFace.PositiveY, 0, null, sfc[i], 0, sfc[i].Length);
            }
            //Negative Y
            sfc = LoadSurface(ref header, reader, out fmt, out w, out h);
            for (int i = 0; i < sfc.Length; i++)
            {
                tex.SetData(CubeMapFace.NegativeY, 0, null, sfc[i], 0, sfc[i].Length);
            }
            //Positive Z
            sfc = LoadSurface(ref header, reader, out fmt, out w, out h);
            for (int i = 0; i < sfc.Length; i++)
            {
                tex.SetData(CubeMapFace.PositiveZ, 0, null, sfc[i], 0, sfc[i].Length);
            }
            //Negative Z
            sfc = LoadSurface(ref header, reader, out fmt, out w, out h);
            for (int i = 0; i < sfc.Length; i++)
            {
                tex.SetData(CubeMapFace.NegativeZ, 0, null, sfc[i], 0, sfc[i].Length);
            }
            return(tex);
        }
コード例 #12
0
 /// <summary>
 /// Reads DDS header from file.
 /// </summary>
 /// <param name="h">Header struct.</param>
 /// <param name="r">File reader.</param>
 public static void Read_DDS_HEADER(DDS_HEADER h, BinaryReader r)
 {
     h.dwSize              = r.ReadInt32();
     h.dwFlags             = r.ReadInt32();
     h.dwHeight            = r.ReadInt32();
     h.dwWidth             = r.ReadInt32();
     h.dwPitchOrLinearSize = r.ReadInt32();
     h.dwDepth             = r.ReadInt32();
     h.dwMipMapCount       = r.ReadInt32();
     for (int i = 0; i < 11; ++i)
     {
         h.dwReserved1[i] = r.ReadInt32();
     }
     Read_DDS_PIXELFORMAT(h.ddspf, r);
     h.dwCaps      = r.ReadInt32();
     h.dwCaps2     = r.ReadInt32();
     h.dwCaps3     = r.ReadInt32();
     h.dwCaps4     = r.ReadInt32();
     h.dwReserved2 = r.ReadInt32();
 }
コード例 #13
0
        /// <summary>
        /// Writes V8U8 DDS header to binary stream.
        /// </summary>
        /// <param name="header">Header to write.</param>
        /// <param name="writer">BinaryWriter wrapped stream to write to.</param>
        private static void Write_V8U8_DDS_Header(DDS_HEADER header, BinaryWriter writer)
        {
            // KFreon: Write magic number ("DDS")
            writer.Write(0x20534444);

            // KFreon: Write all header fields regardless of filled or not
            writer.Write(header.dwSize);
            writer.Write(header.dwFlags);
            writer.Write(header.dwHeight);
            writer.Write(header.dwWidth);
            writer.Write(header.dwPitchOrLinearSize);
            writer.Write(header.dwDepth);
            writer.Write(header.dwMipMapCount);

            // KFreon: Write reserved1
            for (int i = 0; i < 11; i++)
            {
                writer.Write(0);
            }

            // KFreon: Write PIXELFORMAT
            DDS_PIXELFORMAT px = header.ddspf;

            writer.Write(px.dwSize);
            writer.Write(px.dwFlags);
            writer.Write(px.dwFourCC);
            writer.Write(px.dwRGBBitCount);
            writer.Write(px.dwRBitMask);
            writer.Write(px.dwGBitMask);
            writer.Write(px.dwBBitMask);
            writer.Write(px.dwABitMask);

            writer.Write(header.dwCaps);
            writer.Write(header.dwCaps2);
            writer.Write(header.dwCaps3);
            writer.Write(header.dwCaps4);
            writer.Write(header.dwReserved2);
        }
コード例 #14
0
        static int GetSurfaceBytes(ref DDS_HEADER header, int width, int height)
        {
            switch (GetSurfaceFormat(ref header))
            {
            case SurfaceFormat.Dxt1:
                return(((width + 3) / 4) * ((height + 3) / 4) * 8);

            case SurfaceFormat.Dxt3:
            case SurfaceFormat.Dxt5:
                return(((width + 3) / 4) * ((height + 3) / 4) * 16);

            case SurfaceFormat.Bgra5551:
            case SurfaceFormat.Bgr565:
            case SurfaceFormat.Bgra4444:
                return(width * height * 2);

            case SurfaceFormat.Color:
                return(width * height * 4);

            default:
                throw new NotSupportedException(header.ddspf.dwFourCC.ToString());
            }
        }
コード例 #15
0
        /// <summary>
        /// Builds a V8U8 DDS header from certain details.
        /// </summary>
        /// <param name="Mips">Number of mipmaps.</param>
        /// <param name="height">Height of image.</param>
        /// <param name="width">Width of image.</param>
        /// <returns>DDS_HEADER struct from details.</returns>
        private static DDS_HEADER Build_V8U8_DDS_Header(int Mips, int height, int width)
        {
            DDS_HEADER header = new DDS_HEADER();

            header.dwSize        = 124;
            header.dwFlags       = 0x1 | 0x2 | 0x4 | 0x1000 | (Mips != 0 ? 0x20000 : 0x0); // Flags to denote valid fields: DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT
            header.dwWidth       = width;
            header.dwHeight      = height;
            header.dwCaps        = 0x1000 | 0x8 | (Mips == 0 ? 0 : 0x400000);
            header.dwMipMapCount = Mips == 0 ? 1 : Mips;
            //header.dwPitchOrLinearSize = ((width + 1) >> 1)*4;

            DDS_PIXELFORMAT px = new DDS_PIXELFORMAT();

            px.dwSize = 32;
            //px.dwFlags = 0x200;
            px.dwFlags       = 0x80000;
            px.dwRGBBitCount = 16;
            px.dwRBitMask    = 255;
            px.dwGBitMask    = 0x0000FF00;

            header.ddspf = px;
            return(header);
        }
コード例 #16
0
        /// <summary>
        /// Writes V8U8 DDS header to binary stream.
        /// </summary>
        /// <param name="header">Header to write.</param>
        /// <param name="writer">BinaryWriter wrapped stream to write to.</param>
        private static void Write_V8U8_DDS_Header(DDS_HEADER header, BinaryWriter writer)
        {
            // KFreon: Write magic number ("DDS")
            writer.Write(0x20534444);

            // KFreon: Write all header fields regardless of filled or not
            writer.Write(header.dwSize);
            writer.Write(header.dwFlags);
            writer.Write(header.dwHeight);
            writer.Write(header.dwWidth);
            writer.Write(header.dwPitchOrLinearSize);
            writer.Write(header.dwDepth);
            writer.Write(header.dwMipMapCount);

            // KFreon: Write reserved1
            for (int i = 0; i < 11; i++)
                writer.Write(0);

            // KFreon: Write PIXELFORMAT
            DDS_PIXELFORMAT px = header.ddspf;
            writer.Write(px.dwSize);
            writer.Write(px.dwFlags);
            writer.Write(px.dwFourCC);
            writer.Write(px.dwRGBBitCount);
            writer.Write(px.dwRBitMask);
            writer.Write(px.dwGBitMask);
            writer.Write(px.dwBBitMask);
            writer.Write(px.dwABitMask);

            writer.Write(header.dwCaps);
            writer.Write(header.dwCaps2);
            writer.Write(header.dwCaps3);
            writer.Write(header.dwCaps4);
            writer.Write(header.dwReserved2);
        }
コード例 #17
0
        /// <summary>
        /// Builds a V8U8 DDS header from certain details.
        /// </summary>
        /// <param name="Mips">Number of mipmaps.</param>
        /// <param name="height">Height of image.</param>
        /// <param name="width">Width of image.</param>
        /// <returns>DDS_HEADER struct from details.</returns>
        private static DDS_HEADER Build_V8U8_DDS_Header(int Mips, int height, int width)
        {
            DDS_HEADER header = new DDS_HEADER();
            header.dwSize = 124;
            header.dwFlags = 0x1 | 0x2 | 0x4 | 0x1000 | (Mips != 0 ? 0x20000 : 0x0);  // Flags to denote valid fields: DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT | DDSD_MIPMAPCOUNT
            header.dwWidth = width;
            header.dwHeight = height;
            header.dwCaps = 0x1000 | 0x8 | (Mips == 0 ? 0 : 0x400000);
            header.dwMipMapCount = Mips == 0 ? 1 : Mips;
            //header.dwPitchOrLinearSize = ((width + 1) >> 1)*4;

            DDS_PIXELFORMAT px = new DDS_PIXELFORMAT();
            px.dwSize = 32;
            //px.dwFlags = 0x200;
            px.dwFlags = 0x80000;
            px.dwRGBBitCount = 16;
            px.dwRBitMask = 255;
            px.dwGBitMask = 0x0000FF00;

            header.ddspf = px;
            return header;
        }
コード例 #18
0
        public static unsafe Image GetImage(string jitfile)
        {
            using (FileStream fs = new FileStream(jitfile, FileMode.Open)) {
                JITHEADER jitheader;


                byte[] jithdr = new byte[0xc];
                fs.Read(jithdr, 0, jithdr.Length);

                fixed(byte *ptr = &jithdr[0])
                {
                    jitheader = (JITHEADER)Marshal.PtrToStructure((IntPtr)ptr, typeof(JITHEADER));
                }

                DDS_HEADER header = new DDS_HEADER();
                header.magicNumber   = new byte[] { 68, 68, 83, 32 };
                header.ddspf.dwSize  = 32;
                header.dwSize        = 124;
                header.dwHeight      = jitheader.dwHeight;
                header.dwWidth       = jitheader.dwWidth;
                header.ddspf.dwFlags = DWFLAGS.DDPF_FOURCC;

                switch (jitheader.magicNumber)
                {
                case JITSIGN.JT31:
                    header.ddspf.dwFourCC = DWFOURCC.DXT1;
                    break;

                case JITSIGN.JT32:
                    header.ddspf.dwFourCC = DWFOURCC.DXT2;
                    break;

                case JITSIGN.JT33:
                    header.ddspf.dwFourCC = DWFOURCC.DXT3;
                    break;

                case JITSIGN.JT34:
                    header.ddspf.dwFourCC = DWFOURCC.DXT4;
                    break;

                case JITSIGN.JT35:
                    header.ddspf.dwFourCC = DWFOURCC.DXT5;
                    break;
                }


                header.dwMipMapCount = 0;
                header.dwHeaderFlags =
                    DWHEADERFLAGS.DDSD_CAPS |
                    DWHEADERFLAGS.DDSD_HEIGHT |
                    DWHEADERFLAGS.DDSD_WIDTH;
                header.dwSurfaceFlags = DWSURFACEFLAGS.DDSCAPS_TEXTURE;
                header.dwReserved1    = new uint[11];
                header.dwReserved2    = new uint[3];


                byte[] stuff = new byte[fs.Length - 0xc];
                fs.Read(stuff, 0, stuff.Length);

                using (MemoryStream ms = new MemoryStream()) {
                    byte[] hdr = new byte[0x80];
                    fixed(byte *ptr = &hdr[0])
                    {
                        Marshal.StructureToPtr(header, (IntPtr)ptr, false);
                    }

                    ms.Write(hdr, 0, hdr.Length);
                    ms.Write(stuff, 0, stuff.Length);
                    return(DDSDataToBMP(ms.GetBuffer()));
                }
            }
        }
コード例 #19
0
        unsafe public static void ConvertJITToDDS(string jitfile)
        {
            using (FileStream fs = new FileStream(jitfile, FileMode.Open)) {
                JITHEADER jitheader;


                byte[] jithdr = new byte[0xc];
                fs.Read(jithdr, 0, jithdr.Length);

                fixed(byte *ptr = &jithdr[0])
                {
                    jitheader = (JITHEADER)Marshal.PtrToStructure((IntPtr)ptr, typeof(JITHEADER));
                }

                byte[] stuff = new byte[fs.Length - 0xc];
                fs.Read(stuff, 0, stuff.Length);


                using (FileStream dest = new FileStream(jitfile + ".dds", FileMode.Create)) {
                    DDS_HEADER header = new DDS_HEADER();
                    header.magicNumber   = new byte[] { 68, 68, 83, 32 };
                    header.ddspf.dwSize  = 32;
                    header.dwSize        = 124;
                    header.dwHeight      = jitheader.dwHeight;
                    header.dwWidth       = jitheader.dwWidth;
                    header.ddspf.dwFlags = DWFLAGS.DDPF_FOURCC;

                    switch (jitheader.magicNumber)
                    {
                    case JITSIGN.JT31:
                        header.ddspf.dwFourCC = DWFOURCC.DXT1;
                        break;

                    case JITSIGN.JT32:
                        header.ddspf.dwFourCC = DWFOURCC.DXT2;
                        break;

                    case JITSIGN.JT33:
                        header.ddspf.dwFourCC = DWFOURCC.DXT3;
                        break;

                    case JITSIGN.JT34:
                        header.ddspf.dwFourCC = DWFOURCC.DXT4;
                        break;

                    case JITSIGN.JT35:
                        header.ddspf.dwFourCC = DWFOURCC.DXT5;
                        break;
                    }

                    header.dwMipMapCount = 0;
                    //header.dwPitchOrLinearSize = 1048576;
                    header.dwHeaderFlags =
                        DWHEADERFLAGS.DDSD_CAPS |
                        DWHEADERFLAGS.DDSD_HEIGHT |
                        DWHEADERFLAGS.DDSD_WIDTH;
                    header.dwSurfaceFlags = DWSURFACEFLAGS.DDSCAPS_TEXTURE;
                    header.dwReserved1    = new uint[11];
                    header.dwReserved2    = new uint[3];

                    byte[] hdr = new byte[0x80];
                    fixed(byte *ptr = &hdr[0])
                    {
                        Marshal.StructureToPtr(header, (IntPtr)ptr, false);
                    }

                    dest.Write(hdr, 0, hdr.Length);
                    dest.Write(stuff, 0, stuff.Length);
                }
            }
        }
コード例 #20
0
        static Resource CreateTextureFromDDS(Device d3dDevice, DDS_HEADER header, DDS_HEADER_DXT10?header10, byte[] bitData, int offset, int maxsize, out bool isCubeMap)
        {
            int width  = header.width;
            int height = header.height;
            int depth  = header.depth;

            ResourceDimension resDim = ResourceDimension.Unknown;
            int    arraySize         = 1;
            Format format            = Format.Unknown;

            isCubeMap = false;

            int mipCount = header.mipMapCount;

            if (0 == mipCount)
            {
                mipCount = 1;
            }

            if (((header.ddspf.flags & DDS_FOURCC) > 0) && (MAKEFOURCC('D', 'X', '1', '0') == header.ddspf.fourCC))
            {
                DDS_HEADER_DXT10 d3d10ext = header10.Value;

                arraySize = d3d10ext.arraySize;
                if (arraySize == 0)
                {
                    throw new Exception();
                }

                if (BitsPerPixel(d3d10ext.dxgiFormat) == 0)
                {
                    throw new Exception();
                }

                format = d3d10ext.dxgiFormat;

                switch ((ResourceDimension)d3d10ext.resourceDimension)
                {
                case ResourceDimension.Texture1D:
                    // D3DX writes 1D textures with a fixed Height of 1
                    if ((header.flags & DDS_HEIGHT) > 0 && height != 1)
                    {
                        throw new Exception();
                    }
                    height = depth = 1;
                    break;

                case ResourceDimension.Texture2D:
                    //D3D11_RESOURCE_MISC_TEXTURECUBE
                    if ((d3d10ext.miscFlag & 0x4) > 0)
                    {
                        arraySize *= 6;
                        isCubeMap  = true;
                    }
                    depth = 1;
                    break;

                case ResourceDimension.Texture3D:
                    if (!((header.flags & DDS_HEADER_FLAGS_VOLUME) > 0))
                    {
                        throw new Exception();
                    }

                    if (arraySize > 1)
                    {
                        throw new Exception();
                    }
                    break;

                default:
                    throw new Exception();
                }

                resDim = (ResourceDimension)d3d10ext.resourceDimension;
            }
            else
            {
                format = GetDXGIFormat(header.ddspf);

                if (format == Format.Unknown)
                {
                    throw new Exception();
                }

                if ((header.flags & DDS_HEADER_FLAGS_VOLUME) > 0)
                {
                    resDim = ResourceDimension.Texture3D;
                }
                else
                {
                    if ((header.caps2 & DDS_CUBEMAP) > 0)
                    {
                        // We require all six faces to be defined
                        if ((header.caps2 & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES)
                        {
                            throw new Exception();
                        }

                        arraySize = 6;
                        isCubeMap = true;
                    }

                    depth  = 1;
                    resDim = ResourceDimension.Texture2D;
                }
            }
            var resource = d3dDevice.CreateCommittedResource(new HeapProperties(CpuPageProperty.WriteBack, MemoryPool.L0), HeapFlags.None,
                                                             new ResourceDescription()
            {
                //Alignment = -1,
                Dimension         = resDim,
                DepthOrArraySize  = (short)arraySize,
                Flags             = ResourceFlags.None,
                Format            = format,
                Height            = height,
                Layout            = TextureLayout.Unknown,
                MipLevels         = (short)mipCount,
                SampleDescription = new SampleDescription(1, 0),
                Width             = width,
            },
                                                             ResourceStates.GenericRead);

            FillInitData(resource, width, height, depth, mipCount, arraySize, format, 0, 0, bitData, offset);

            return(resource);
        }
コード例 #21
0
        /// <summary>
        /// Parses the data from a DDS byte array. (Can also read just the header only)
        /// </summary>
        /// <param name="fileData"></param>
        /// <param name="headerOnly"></param>
        private void GetData(byte[] fileData, bool headerOnly)
        {
            ConsoleFunctions.SetConsoleColor(ConsoleColor.Black, ConsoleColor.White);
            Console.WriteLine("Total Source Texture Byte Size = {0}", fileData.Length);

            //which byte offset we are on for the source texture (will be changed as we go through the file)
            byte[] headerBytes = ByteFunctions.AllocateBytes(124, fileData, 4); //skip past the 'DDS '

            //this will automatically read all of the byte data in the header
            header = DDS_Functions.GetHeaderFromBytes(headerBytes);

            ConsoleFunctions.SetConsoleColor(ConsoleColor.Black, ConsoleColor.White);
            Console.WriteLine("DDS Height = {0}", header.dwHeight);
            Console.WriteLine("DDS Width = {0}", header.dwWidth);
            Console.WriteLine("DDS Mip Map Count = {0}", header.dwMipMapCount);
            Console.WriteLine("DDS Compression = {0}", header.ddspf.dwFourCC);

            if (headerOnly)
            {
                return;
            }

            //--------------------------EXTRACT DDS TEXTURE DATA--------------------------
            //calculate dds header length (we add 4 because we skipped the 4 bytes which contain the ddsPrefix, it isn't necessary to parse this data)
            uint ddsHeaderLength = 4 + header.dwSize;

            //calculate the length of just the dds texture data
            uint ddsTextureDataLength = (uint)sourceFileData.Length - ddsHeaderLength;

            //allocate a byte array of dds texture length
            byte[] ddsTextureData = new byte[ddsTextureDataLength];

            //copy the data from the source byte array past the header (so we are only getting texture data)
            Array.Copy(sourceFileData, ddsHeaderLength, ddsTextureData, 0, ddsTextureData.Length);

            //if there are no mip maps
            if (header.dwMipMapCount <= 1)
            {
                textureData = new();
                textureData.Add(ddsTextureData);
                Console.WriteLine("DDS Texture Byte Size = {0}", textureData[0].Length);
            }
            else //if there are mip maps
            {
                //get mip resolutions
                //calculated mip resolutions [Pixel Value, Width or Height (0 or 1)]
                mipMapResolutions = DDS_Functions.DDS_CalculateMipResolutions(header.dwMipMapCount, header.dwWidth, header.dwHeight);

                //get byte sizes
                uint[] byteSizes = DDS_Functions.DDS_GetImageByteSizes(mipMapResolutions, DDS_Functions.DDS_CompressionBool(header));

                textureData = new();
                int test   = ddsTextureData.Length;
                int offset = 0;

                for (int i = 0; i < byteSizes.Length; i++)
                {
                    byte[] temp = new byte[byteSizes[i]];

                    //issue length
                    Array.Copy(ddsTextureData, offset, temp, 0, temp.Length);

                    offset += temp.Length - 1;

                    textureData.Add(temp);

                    test -= (int)byteSizes[i];
                }
            }
        }
コード例 #22
0
ファイル: ImageFormats.cs プロジェクト: LazyBone152/XV2-Tools
        /// <summary>
        /// Gets Format of image.
        /// </summary>
        /// <param name="imgData">Stream containing entire image. NOT just pixels.</param>
        /// <param name="extension">Type of file.</param>
        /// <returns>Format of image.</returns>
        public static Format ParseFormat(Stream imgData, SupportedExtensions extension, ref DDS_HEADER header)
        {
            switch (extension)
            {
            case SupportedExtensions.BMP:
                return(new Format(ImageEngineFormat.BMP));

            case SupportedExtensions.DDS:
                return(ParseDDSFormat(imgData, out header));

            case SupportedExtensions.JPG:
                return(new Format(ImageEngineFormat.JPG));

            case SupportedExtensions.PNG:
                return(new Format(ImageEngineFormat.PNG));

            case SupportedExtensions.TGA:
                return(new Format(ImageEngineFormat.TGA));
            }

            return(new Format());
        }
コード例 #23
0
ファイル: JitConverter.cs プロジェクト: davidsiaw/aiondb
        public static unsafe void ConvertJITToDDS(string jitfile)
        {
            using (FileStream fs = new FileStream(jitfile, FileMode.Open)) {

                JITHEADER jitheader;

                byte[] jithdr = new byte[0xc];
                fs.Read(jithdr, 0, jithdr.Length);

                fixed (byte* ptr = &jithdr[0]) {
                    jitheader = (JITHEADER)Marshal.PtrToStructure((IntPtr)ptr, typeof(JITHEADER));
                }

                byte[] stuff = new byte[fs.Length - 0xc];
                fs.Read(stuff, 0, stuff.Length);

                using (FileStream dest = new FileStream(jitfile + ".dds", FileMode.Create)) {

                    DDS_HEADER header = new DDS_HEADER();
                    header.magicNumber = new byte[] { 68, 68, 83, 32 };
                    header.ddspf.dwSize = 32;
                    header.dwSize = 124;
                    header.dwHeight = jitheader.dwHeight;
                    header.dwWidth = jitheader.dwWidth;
                    header.ddspf.dwFlags = DWFLAGS.DDPF_FOURCC;

                    switch (jitheader.magicNumber) {
                        case JITSIGN.JT31:
                            header.ddspf.dwFourCC = DWFOURCC.DXT1;
                            break;
                        case JITSIGN.JT32:
                            header.ddspf.dwFourCC = DWFOURCC.DXT2;
                            break;
                        case JITSIGN.JT33:
                            header.ddspf.dwFourCC = DWFOURCC.DXT3;
                            break;
                        case JITSIGN.JT34:
                            header.ddspf.dwFourCC = DWFOURCC.DXT4;
                            break;
                        case JITSIGN.JT35:
                            header.ddspf.dwFourCC = DWFOURCC.DXT5;
                            break;
                    }

                    header.dwMipMapCount = 0;
                    //header.dwPitchOrLinearSize = 1048576;
                    header.dwHeaderFlags =
                        DWHEADERFLAGS.DDSD_CAPS |
                        DWHEADERFLAGS.DDSD_HEIGHT |
                        DWHEADERFLAGS.DDSD_WIDTH;
                    header.dwSurfaceFlags = DWSURFACEFLAGS.DDSCAPS_TEXTURE;
                    header.dwReserved1 = new uint[11];
                    header.dwReserved2 = new uint[3];

                    byte[] hdr = new byte[0x80];
                    fixed (byte* ptr = &hdr[0]) {
                        Marshal.StructureToPtr(header, (IntPtr)ptr, false);
                    }

                    dest.Write(hdr, 0, hdr.Length);
                    dest.Write(stuff, 0, stuff.Length);

                }

            }
        }
コード例 #24
0
ファイル: DDSLoader.cs プロジェクト: tungcheng/UnityHelpers
        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);
        }
コード例 #25
0
ファイル: DDSConverter.cs プロジェクト: mmalewski/Crucible-1
        public unsafe static void SaveDDS(IFilesystemEntry file, string path = null)
        {
            var filesystem        = file.Filesystem;
            var filesystemManager = filesystem.FilesystemManager;
            var searchName        = file.FullPath;


            var rawData             = file.GetData();
            BinaryBlobReader reader = new BinaryBlobReader(rawData, 0);

            bool isDX10 = false;

            UInt32 dwMagic = reader.ReadUInt32();

            if (dwMagic != uchar32("DDS "))
            {
                throw new Exception("Invalid dds file");
            }
            DDS_HEADER       header = reader.Read <DDS_HEADER>();
            DDS_HEADER_DXT10 header10;

            if (header.dwSize != sizeof(DDS_HEADER))
            {
                throw new Exception("Invalid header size");
            }

            bool fourCCFlag = (header.ddspf.dwFlags & DDS_PIXELFORMAT_FLAGS.DDPF_FOURCC) != 0;

            if (fourCCFlag)
            {
                isDX10 = header.ddspf.dwFourCC == uchar32("DX10");
                if (isDX10)
                {
                    header10 = reader.Read <DDS_HEADER_DXT10>();
                }
            }

            var max_dimension = Math.Min(header.dwWidth, header.dwHeight);
            var mips          = (int)Math.Log((double)max_dimension, 2.0);
            var extra_mips    = Math.Max(mips - 4, 0);

            // hack: there must be a better way to tell
            bool isCubemap = file.Name.EndsWith("_cm_diff.dds", StringComparison.OrdinalIgnoreCase);

            if (isCubemap)
            {
                var index         = searchName.IndexOf("_cm_diff.dds", StringComparison.OrdinalIgnoreCase);
                var prefix        = searchName.Substring(0, index);
                var newSearchName = prefix + "_cm.dds";
                searchName = newSearchName;
            }

            var isNormal = false;

            isNormal |= searchName.EndsWith("ddna.dds", StringComparison.OrdinalIgnoreCase);
            isNormal |= searchName.EndsWith("ddn.dds", StringComparison.OrdinalIgnoreCase);

            byte[] allData;
            {
                List <byte> allDataBuffer   = new List <byte>(rawData);
                List <byte> alphaDataBuffer = new List <byte>(0);

                var chunkFileAlphaPath = $"{searchName}.a";
                var chunkFileAlpha     = filesystem[chunkFileAlphaPath];
                if (chunkFileAlpha != null) //todo programatically determine alpha existance
                {
                    var dataChunkAlpha = chunkFileAlpha.GetData();

                    BinaryBlobReader alphaReader = new BinaryBlobReader(dataChunkAlpha, 0);
                    DDS_HEADER       alphaHeader = reader.Read <DDS_HEADER>();
                    DDS_HEADER_DXT10 alphaHeader10;
                    if (isDX10)
                    {
                        alphaHeader10 = reader.Read <DDS_HEADER_DXT10>();
                    }
                    var remainderBytes = reader.Read <byte>((int)(dataChunkAlpha.LongLength - reader.Position));

                    alphaDataBuffer.AddRange(remainderBytes);
                    //alphaDataBuffer.AddRange(dataChunkAlpha);

                    for (int i = 1; i <= extra_mips; i++)
                    {
                        chunkFileAlphaPath = $"{searchName}.{i}a";
                        chunkFileAlpha     = filesystem[chunkFileAlphaPath];
                        dataChunkAlpha     = chunkFileAlpha.GetData();

                        alphaDataBuffer.AddRange(dataChunkAlpha);
                    }
                }

                for (int i = 1; i <= extra_mips; i++)
                {
                    var chunkFilePath = $"{searchName}.{i}";
                    var chunkFile     = filesystem[chunkFilePath];

                    if (chunkFile == null)
                    {
                        //throw new Exception($"Data chunk {chunkFilePath} missing!");
                        continue; // this is valid for some files
                    }
                    var dataChunk = chunkFile.GetData();

                    allDataBuffer.AddRange(dataChunk);
                }
                allDataBuffer.AddRange(alphaDataBuffer);
                allData = allDataBuffer.ToArray();
            }

            string fullPath;
            var    baseDirectory = path ?? filesystemManager.DirectoryName;

            if (file.IsDirectory)
            {
                fullPath = Path.Combine(baseDirectory, searchName);
            }
            else
            {
                fullPath = path ?? Path.Combine(baseDirectory, searchName);
            }
            var fullDirectory = Path.GetDirectoryName(fullPath);

            Directory.CreateDirectory(fullDirectory);
            using (FileStream fs = new FileStream(fullPath, FileMode.Create, FileAccess.Write))
            {
                fs.Write(allData, 0, allData.Length);
            }
            if (!isCubemap)
            {
                var tiffPath = Path.ChangeExtension(fullPath, ".tiff");
                try
                {
                    var tiffData = ImageProcessing.DDS.Convert(allData, isNormal);
                    using (FileStream fs = new FileStream(tiffPath, FileMode.Create, FileAccess.Write))
                    {
                        fs.Write(tiffData, 0, tiffData.Length);
                    }
                }
                catch (Exception e)
                {
                    MainWindow.SetStatus($"Failed to save TIFF {tiffPath} | {e.Message}");
                }
            }
        }
コード例 #26
0
        public static Format TextureInfo(byte[] data)
        {
            // bool isCubeMap;

            // Validate DDS file in memory
            DDS_HEADER header = new DDS_HEADER();

            int ddsHeaderSize   = Marshal.SizeOf(header);
            int ddspfSize       = Marshal.SizeOf(new DDS_PIXELFORMAT());
            int ddsHeader10Size = Marshal.SizeOf(new DDS_HEADER_DXT10());

            if (data.Length < (sizeof(uint) + ddsHeaderSize))
            {
                throw new Exception();
            }

            //first is magic number
            int dwMagicNumber = BitConverter.ToInt32(data, 0);

            if (dwMagicNumber != DDS_MAGIC)
            {
                throw new Exception();
            }

            header = ByteArrayToStructure <DDS_HEADER>(data, 4, ddsHeaderSize);

            // Verify header to validate DDS file
            if (header.size != ddsHeaderSize || header.ddspf.size != ddspfSize)
            {
                throw new Exception();
            }

            // Check for DX10 extension
            bool bDXT10Header = false;

            if (((header.ddspf.flags & DDS_FOURCC) > 0) && (MAKEFOURCC('D', 'X', '1', '0') == header.ddspf.fourCC))
            {
                // Must be long enough for both headers and magic value
                if (data.Length < (ddsHeaderSize + 4 + ddsHeader10Size))
                {
                    throw new Exception();
                }

                bDXT10Header = true;
            }

            int offset = 4 + ddsHeaderSize + (bDXT10Header ? ddsHeader10Size : 0);

            // return InitTextureFromData(device, context, header, null, data, offset, 0, out isCubeMap);
            // return InitTextureFromData(device, context, header, null, data, offset, 0, out isCubeMap);
            // return InitTextureFromData(device, context, header, null, data, offset, 0, out isCubeMap);

            DDS_HEADER_DXT10?header10 = null;

            if (bDXT10Header)
            {
                header10 = ByteArrayToStructure <DDS_HEADER_DXT10>(data, 4 + ddsHeaderSize, ddsHeader10Size);
            }

            int width  = header.width;
            int height = header.height;
            int depth  = header.depth;

            D3D10_RESOURCE_DIMENSION resDim = D3D10_RESOURCE_DIMENSION.UNKNOWN;
            int    arraySize = 1;
            Format format    = Format.UNKNOWN;
            // isCubeMap = false;

            int mipCount = header.mipMapCount;

            if (0 == mipCount)
            {
                mipCount = 1;
            }

            if (((header.ddspf.flags & DDS_FOURCC) > 0) && (MAKEFOURCC('D', 'X', '1', '0') == header.ddspf.fourCC))
            {
                DDS_HEADER_DXT10 d3d10ext = header10.Value;

                arraySize = d3d10ext.arraySize;
                if (arraySize == 0)
                {
                    throw new Exception();
                }

                if (BitsPerPixel(d3d10ext.dxgiFormat) == 0)
                {
                    throw new Exception();
                }

                format = d3d10ext.dxgiFormat;

                switch ((D3D10_RESOURCE_DIMENSION)d3d10ext.resourceDimension)
                {
                case D3D10_RESOURCE_DIMENSION.TEXTURE1D:
                    // D3DX writes 1D textures with a fixed Height of 1
                    if ((header.flags & DDS_HEIGHT) > 0 && height != 1)
                    {
                        throw new Exception();
                    }
                    height = depth = 1;
                    break;

                case D3D10_RESOURCE_DIMENSION.TEXTURE2D:
                    //D3D11_RESOURCE_MISC_TEXTURECUBE
                    if ((d3d10ext.miscFlag & 0x4) > 0)
                    {
                        arraySize *= 6;
                        // isCubeMap = true;
                    }
                    depth = 1;
                    break;

                case D3D10_RESOURCE_DIMENSION.TEXTURE3D:
                    if (!((header.flags & DDS_HEADER_FLAGS_VOLUME) > 0))
                    {
                        throw new Exception();
                    }

                    if (arraySize > 1)
                    {
                        throw new Exception();
                    }
                    break;

                default:
                    throw new Exception();
                }

                resDim = (D3D10_RESOURCE_DIMENSION)d3d10ext.resourceDimension;
            }
            else
            {
                format = GetDXGIFormat(header.ddspf);

                if (format == Format.UNKNOWN)
                {
                    throw new Exception();
                }

                if ((header.flags & DDS_HEADER_FLAGS_VOLUME) > 0)
                {
                    resDim = D3D10_RESOURCE_DIMENSION.TEXTURE3D;
                }
                else
                {
                    if ((header.caps2 & DDS_CUBEMAP) > 0)
                    {
                        // We require all six faces to be defined
                        if ((header.caps2 & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES)
                        {
                            throw new Exception();
                        }

                        arraySize = 6;
                        // isCubeMap = true;
                    }

                    depth  = 1;
                    resDim = D3D10_RESOURCE_DIMENSION.TEXTURE2D;
                }
            }

            return(format);
        }
コード例 #27
0
        private void LoadImage(Stream stream)
        {
            stream.Seek(0, SeekOrigin.Begin);
            BinaryReader r = new BinaryReader(stream);
            int dwMagic = r.ReadInt32();
            if (dwMagic != 0x20534444)
                throw new Exception("This is not a DDS! Magic number wrong.");

            DDS_HEADER header = new DDS_HEADER();
            Read_DDS_HEADER(header, r);

            if (((header.ddspf.dwFlags & 0x00000004) != 0) && (header.ddspf.dwFourCC == 0x30315844 /*DX10*/))
            {
                throw new Exception("DX10 not supported yet!");
            }

            if (header.ddspf.dwFourCC != 0)
                throw new InvalidDataException("DDS not V8U8.");

            int mipMapCount = 1;
            if ((header.dwFlags & 0x00020000) != 0)
                mipMapCount = header.dwMipMapCount;

            int w = 0;
            int h = 0;

            double bytePerPixel = 2;
            MipMaps = new MipMap[mipMapCount];

            // KFreon: Get mips
            for (int i = 0; i < mipMapCount; i++)
            {
                w = (int)(header.dwWidth / Math.Pow(2, i));
                h = (int)(header.dwHeight / Math.Pow(2, i));

                int mipMapBytes = (int)(w * h * bytePerPixel);
                MipMaps[i] = new MipMap(r.ReadBytes(mipMapBytes), w, h);
            }

            Width = header.dwWidth;
            Height = header.dwHeight;
        }
コード例 #28
0
ファイル: JitConverter.cs プロジェクト: davidsiaw/aiondb
        public static unsafe Image GetImage(string jitfile)
        {
            using (FileStream fs = new FileStream(jitfile, FileMode.Open)) {

                JITHEADER jitheader;

                byte[] jithdr = new byte[0xc];
                fs.Read(jithdr, 0, jithdr.Length);

                fixed (byte* ptr = &jithdr[0]) {
                    jitheader = (JITHEADER)Marshal.PtrToStructure((IntPtr)ptr, typeof(JITHEADER));
                }

                DDS_HEADER header = new DDS_HEADER();
                header.magicNumber = new byte[] { 68, 68, 83, 32 };
                header.ddspf.dwSize = 32;
                header.dwSize = 124;
                header.dwHeight = jitheader.dwHeight;
                header.dwWidth = jitheader.dwWidth;
                header.ddspf.dwFlags = DWFLAGS.DDPF_FOURCC;

                switch (jitheader.magicNumber) {
                    case JITSIGN.JT31:
                        header.ddspf.dwFourCC = DWFOURCC.DXT1;
                        break;
                    case JITSIGN.JT32:
                        header.ddspf.dwFourCC = DWFOURCC.DXT2;
                        break;
                    case JITSIGN.JT33:
                        header.ddspf.dwFourCC = DWFOURCC.DXT3;
                        break;
                    case JITSIGN.JT34:
                        header.ddspf.dwFourCC = DWFOURCC.DXT4;
                        break;
                    case JITSIGN.JT35:
                        header.ddspf.dwFourCC = DWFOURCC.DXT5;
                        break;
                }

                header.dwMipMapCount = 0;
                header.dwHeaderFlags =
                    DWHEADERFLAGS.DDSD_CAPS |
                    DWHEADERFLAGS.DDSD_HEIGHT |
                    DWHEADERFLAGS.DDSD_WIDTH;
                header.dwSurfaceFlags = DWSURFACEFLAGS.DDSCAPS_TEXTURE;
                header.dwReserved1 = new uint[11];
                header.dwReserved2 = new uint[3];

                byte[] stuff = new byte[fs.Length - 0xc];
                fs.Read(stuff, 0, stuff.Length);

                using (MemoryStream ms = new MemoryStream()) {

                    byte[] hdr = new byte[0x80];
                    fixed (byte* ptr = &hdr[0]) {
                        Marshal.StructureToPtr(header, (IntPtr)ptr, false);
                    }
                    ms.Write(hdr, 0, hdr.Length);
                    ms.Write(stuff, 0, stuff.Length);
                    return DDSDataToBMP(ms.GetBuffer());
                }

            }
        }
コード例 #29
0
ファイル: ImageFormats.cs プロジェクト: LazyBone152/XV2-Tools
        /// <summary>
        /// Reads DDS format from DDS Header.
        /// Not guaranteed to work. Format 'optional' in header.
        /// </summary>
        /// <param name="stream">Stream containing full image file. NOT just pixels.</param>
        /// <param name="header">DDS Header information.</param>
        /// <returns>Format of DDS.</returns>
        internal static Format ParseDDSFormat(Stream stream, out DDS_HEADER header)
        {
            Format format = new Format(ImageEngineFormat.DDS_ARGB);

            stream.Seek(0, SeekOrigin.Begin);
            using (BinaryReader reader = new BinaryReader(stream, Encoding.Default, true))
            {
                header = null;

                // KFreon: Check image is a DDS
                int Magic = reader.ReadInt32();
                if (Magic != 0x20534444)
                {
                    return(new Format());  // KFreon: Not a DDS
                }
                header = new DDS_HEADER();
                Read_DDS_HEADER(header, reader);


                if (((header.ddspf.dwFlags & 0x00000004) != 0) && (header.ddspf.dwFourCC == 0x30315844 /*DX10*/))
                {
                    throw new Exception("DX10 not supported yet!");
                }

                format = ImageFormats.ParseFourCC(header.ddspf.dwFourCC);

                if (format.SurfaceFormat == ImageEngineFormat.Unknown || format.SurfaceFormat == ImageEngineFormat.DDS_ARGB)
                {
                    // KFreon: Apparently all these flags mean it's a V8U8 image...
                    if (header.ddspf.dwRGBBitCount == 0x10 &&
                        header.ddspf.dwRBitMask == 0xFF &&
                        header.ddspf.dwGBitMask == 0xFF00 &&
                        header.ddspf.dwBBitMask == 0x00 &&
                        header.ddspf.dwABitMask == 0x00)
                    {
                        format = new Format(ImageEngineFormat.DDS_V8U8);  // KFreon: V8U8
                    }
                    // KFreon: Test for L8/G8
                    else if (header.ddspf.dwABitMask == 0 &&
                             header.ddspf.dwBBitMask == 0 &&
                             header.ddspf.dwGBitMask == 0 &&
                             header.ddspf.dwRBitMask == 255 &&
                             header.ddspf.dwFlags == 131072 &&
                             header.ddspf.dwSize == 32 &&
                             header.ddspf.dwRGBBitCount == 8)
                    {
                        format = new Format(ImageEngineFormat.DDS_G8_L8);
                    }

                    // KFreon: A8L8. This can probably be something else as well, but it seems to work for now
                    else if (header.ddspf.dwRGBBitCount == 16)
                    {
                        format = new Format(ImageEngineFormat.DDS_A8L8);
                    }

                    // KFreon: RGB test.
                    else if (header.ddspf.dwRGBBitCount == 24)
                    {
                        format = new Format(ImageEngineFormat.DDS_RGB);
                    }
                }
            }
            return(format);
        }
コード例 #30
0
 /// <summary>
 /// Reads DDS header from file.
 /// </summary>
 /// <param name="h">Header struct.</param>
 /// <param name="r">File reader.</param>
 public static void Read_DDS_HEADER(DDS_HEADER h, BinaryReader r)
 {
     h.dwSize = r.ReadInt32();
     h.dwFlags = r.ReadInt32();
     h.dwHeight = r.ReadInt32();
     h.dwWidth = r.ReadInt32();
     h.dwPitchOrLinearSize = r.ReadInt32();
     h.dwDepth = r.ReadInt32();
     h.dwMipMapCount = r.ReadInt32();
     for (int i = 0; i < 11; ++i)
     {
         h.dwReserved1[i] = r.ReadInt32();
     }
     Read_DDS_PIXELFORMAT(h.ddspf, r);
     h.dwCaps = r.ReadInt32();
     h.dwCaps2 = r.ReadInt32();
     h.dwCaps3 = r.ReadInt32();
     h.dwCaps4 = r.ReadInt32();
     h.dwReserved2 = r.ReadInt32();
 }
コード例 #31
0
        /// <summary>
        /// Create a DDS file from a D3DTX
        /// </summary>
        /// <param name="d3dtx"></param>
        public DDS_Master(D3DTX_Master d3dtx)
        {
            header = DDS_Functions.GetPresetHeader();
            T3SurfaceFormat surfaceFormat = T3SurfaceFormat.eSurface_DXT1;

            if (d3dtx.d3dtx4 != null)
            {
                header.dwWidth       = d3dtx.d3dtx4.mWidth;
                header.dwHeight      = d3dtx.d3dtx4.mHeight;
                header.dwMipMapCount = d3dtx.d3dtx4.mNumMipLevels;
                surfaceFormat        = d3dtx.d3dtx4.mSurfaceFormat;
            }
            else if (d3dtx.d3dtx5 != null)
            {
                header.dwWidth       = d3dtx.d3dtx5.mWidth;
                header.dwHeight      = d3dtx.d3dtx5.mHeight;
                header.dwMipMapCount = d3dtx.d3dtx5.mNumMipLevels;
                surfaceFormat        = d3dtx.d3dtx5.mSurfaceFormat;
            }
            else if (d3dtx.d3dtx6 != null)
            {
                header.dwWidth       = d3dtx.d3dtx6.mWidth;
                header.dwHeight      = d3dtx.d3dtx6.mHeight;
                header.dwMipMapCount = d3dtx.d3dtx6.mNumMipLevels;
                surfaceFormat        = d3dtx.d3dtx6.mSurfaceFormat;
            }
            else if (d3dtx.d3dtx7 != null)
            {
                header.dwWidth       = d3dtx.d3dtx7.mWidth;
                header.dwHeight      = d3dtx.d3dtx7.mHeight;
                header.dwMipMapCount = d3dtx.d3dtx7.mNumMipLevels;
                //header.dwDepth = d3dtx.d3dtx7.mDepth;
                surfaceFormat = d3dtx.d3dtx7.mSurfaceFormat;
            }
            else if (d3dtx.d3dtx8 != null)
            {
                header.dwWidth       = d3dtx.d3dtx8.mWidth;
                header.dwHeight      = d3dtx.d3dtx8.mHeight;
                header.dwMipMapCount = d3dtx.d3dtx8.mNumMipLevels;
                header.dwDepth       = d3dtx.d3dtx8.mDepth;
                surfaceFormat        = d3dtx.d3dtx8.mSurfaceFormat;
            }
            else if (d3dtx.d3dtx9 != null)
            {
                header.dwWidth       = d3dtx.d3dtx9.mWidth;
                header.dwHeight      = d3dtx.d3dtx9.mHeight;
                header.dwMipMapCount = d3dtx.d3dtx9.mNumMipLevels;
                header.dwDepth       = d3dtx.d3dtx9.mDepth;
                surfaceFormat        = d3dtx.d3dtx9.mSurfaceFormat;
            }

            DDS_PIXELFORMAT new_ddspf = new DDS_PIXELFORMAT();

            new_ddspf.dwFourCC = DDS_Functions.Get_FourCC_FromTellale(surfaceFormat);

            switch (surfaceFormat)
            {
            case Telltale.T3SurfaceFormat.eSurface_A8:
                new_ddspf.dwABitMask = 255;
                header.dwCaps        = 4198408; //DDSCAPS_COMPLEX | DDSCAPS_TEXTURE | DDSCAPS_MIPMAP
                break;

            case Telltale.T3SurfaceFormat.eSurface_ARGB8:
                new_ddspf.dwABitMask = 255;
                new_ddspf.dwRBitMask = 255;
                new_ddspf.dwGBitMask = 255;
                new_ddspf.dwBBitMask = 255;
                header.dwCaps        = 4198408; //DDSCAPS_COMPLEX | DDSCAPS_TEXTURE | DDSCAPS_MIPMAP
                break;
            }

            header.ddspf = new_ddspf;
        }
コード例 #32
0
        static bool? IsV8U8(Stream stream)
        {
            stream.Seek(0, SeekOrigin.Begin);
            using (BinaryReader r = new BinaryReader(stream, Encoding.Default, true))
            {
                int dwMagic = r.ReadInt32();
                if (dwMagic != 0x20534444)
                    return null;

                DDS_HEADER header = new DDS_HEADER();
                Read_DDS_HEADER(header, r);

                if (((header.ddspf.dwFlags & 0x00000004) != 0) && (header.ddspf.dwFourCC == 0x30315844 /*DX10*/))
                {
                    throw new Exception("DX10 not supported yet!");
                }
                return header.ddspf.dwRGBBitCount == 0x10 &&
                           header.ddspf.dwRBitMask == 0xFF &&
                           header.ddspf.dwGBitMask == 0xFF00 &&
                           header.ddspf.dwBBitMask == 0x00 &&
                           header.ddspf.dwABitMask == 0x00;
            }
        }
コード例 #33
0
        private static ShaderResourceView InitTextureFromData(Device d3dDevice, DeviceContext context, DDS_HEADER header, DDS_HEADER_DXT10?header10, byte[] bitData, int offset, int maxsize, out bool isCubeMap)
        {
            int width  = header.width;
            int height = header.height;
            int depth  = header.depth;

            ResourceDimension resDim = ResourceDimension.Unknown;
            int    arraySize         = 1;
            Format format            = Format.Unknown;

            isCubeMap = false;

            int mipCount = header.mipMapCount;

            if (0 == mipCount)
            {
                mipCount = 1;
            }

            if (((header.ddspf.flags & DDS_FOURCC) > 0) && (MAKEFOURCC('D', 'X', '1', '0') == header.ddspf.fourCC))
            {
                DDS_HEADER_DXT10 d3d10ext = header10.Value;

                arraySize = d3d10ext.arraySize;
                if (arraySize == 0)
                {
                    throw new Exception();
                }

                if (BitsPerPixel(d3d10ext.dxgiFormat) == 0)
                {
                    throw new Exception();
                }

                format = d3d10ext.dxgiFormat;

                switch ((ResourceDimension)d3d10ext.resourceDimension)
                {
                case ResourceDimension.Texture1D:
                    // D3DX writes 1D textures with a fixed Height of 1
                    if ((header.flags & DDS_HEIGHT) > 0 && height != 1)
                    {
                        throw new Exception();
                    }
                    height = depth = 1;
                    break;

                case ResourceDimension.Texture2D:
                    //D3D11_RESOURCE_MISC_TEXTURECUBE
                    if ((d3d10ext.miscFlag & 0x4) > 0)
                    {
                        arraySize *= 6;
                        isCubeMap  = true;
                    }
                    depth = 1;
                    break;

                case ResourceDimension.Texture3D:
                    if (!((header.flags & DDS_HEADER_FLAGS_VOLUME) > 0))
                    {
                        throw new Exception();
                    }

                    if (arraySize > 1)
                    {
                        throw new Exception();
                    }
                    break;

                default:
                    throw new Exception();
                }

                resDim = (ResourceDimension)d3d10ext.resourceDimension;
            }
            else
            {
                format = GetDXGIFormat(header.ddspf);

                if (format == Format.Unknown)
                {
                    throw new Exception();
                }

                if ((header.flags & DDS_HEADER_FLAGS_VOLUME) > 0)
                {
                    resDim = ResourceDimension.Texture3D;
                }
                else
                {
                    if ((header.caps2 & DDS_CUBEMAP) > 0)
                    {
                        // We require all six faces to be defined
                        if ((header.caps2 & DDS_CUBEMAP_ALLFACES) != DDS_CUBEMAP_ALLFACES)
                        {
                            throw new Exception();
                        }

                        arraySize = 6;
                        isCubeMap = true;
                    }

                    depth  = 1;
                    resDim = ResourceDimension.Texture2D;
                }
            }

            Resource resource = null;


            GCHandle pinnedArray = GCHandle.Alloc(bitData, GCHandleType.Pinned);
            IntPtr   pointer     = pinnedArray.AddrOfPinnedObject();
            var      boxes       = FillInitData(pointer, width, height, depth, mipCount, arraySize, format, 0, 0, offset);


            switch (resDim)
            {
            case ResourceDimension.Unknown:
                break;

            case ResourceDimension.Buffer:
                break;

            case ResourceDimension.Texture1D:
                resource = new Texture1D(d3dDevice, new Texture1DDescription()
                {
                    BindFlags      = BindFlags.ShaderResource,
                    Format         = format,
                    ArraySize      = arraySize,
                    Width          = width,
                    CpuAccessFlags = CpuAccessFlags.None,
                    MipLevels      = mipCount,
                    OptionFlags    = ResourceOptionFlags.None,
                    Usage          = ResourceUsage.Default,
                }, boxes.ToArray());
                break;

            case ResourceDimension.Texture2D:
                resource = new Texture2D(d3dDevice, new Texture2DDescription()
                {
                    ArraySize         = arraySize,
                    BindFlags         = BindFlags.ShaderResource,
                    Format            = format,
                    Height            = height,
                    Width             = width,
                    CpuAccessFlags    = CpuAccessFlags.None,
                    MipLevels         = mipCount,
                    OptionFlags       = ResourceOptionFlags.None,
                    SampleDescription = new SampleDescription(1, 0),
                    Usage             = ResourceUsage.Default
                }, boxes.ToArray());
                break;

            case ResourceDimension.Texture3D:
                resource = new Texture3D(d3dDevice, new Texture3DDescription()
                {
                    Depth          = depth,
                    BindFlags      = BindFlags.ShaderResource,
                    Format         = format,
                    Height         = height,
                    Width          = width,
                    CpuAccessFlags = CpuAccessFlags.None,
                    MipLevels      = mipCount,
                    OptionFlags    = ResourceOptionFlags.None,
                    Usage          = ResourceUsage.Default
                }, boxes.ToArray());
                break;

            default:
                break;
            }
            pinnedArray.Free();


            var resourceView = new ShaderResourceView(d3dDevice, resource);

            return(resourceView);
        }
コード例 #34
0
        static byte[][] LoadSurface(ref DDS_HEADER header, BinaryReader reader, out SurfaceFormat fmt, out int width, out int height)
        {
            width  = (int)header.dwWidth;
            height = (int)header.dwHeight;
            int mipMapCount = 1;

            if (CheckFlag(header.dwCaps, DDSCAPS_MIPMAP) ||
                CheckFlag(header.dwFlags, DDSD_MIPMAPCOUNT))
            {
                mipMapCount = (int)header.dwMipMapCount;
            }
            var sfc = new List <byte[]>();

            fmt = GetSurfaceFormat(ref header);
            int w = width, h = height;

            for (int i = 0; i < mipMapCount; i++)
            {
                var length = GetSurfaceBytes(ref header, w, h);

                var    bytes = GetSurfaceBytes(ref header, w, h);
                byte[] data;
                if (fmt == SurfaceFormat.Color && header.ddspf.dwRGBBitCount == 24)
                {
                    data = new byte[bytes];
                    for (int j = 0; j < bytes; j += 4)
                    {
                        data[j]     = reader.ReadByte();
                        data[j + 1] = reader.ReadByte();
                        data[j + 2] = reader.ReadByte();
                    }
                }
                else
                {
                    data = reader.ReadBytes(bytes);
                }
                //If no alpha
                if (fmt == SurfaceFormat.Color && header.ddspf.dwABitMask == 0)
                {
                    for (int px = 0; px < bytes; px += 4)
                    {
                        data[px + 3] = 255;
                    }
                }
                //Swap channels if needed
                if (fmt == SurfaceFormat.Color && header.ddspf.dwRBitMask == 0xff0000)
                {
                    for (int px = 0; px < bytes; px += 4)
                    {
                        var g = data[px];
                        var b = data[px + 2];
                        data[px]     = b;
                        data[px + 2] = g;
                    }
                }
                sfc.Add(data);

                w /= 2;
                h /= 2;
                if (w < 1)
                {
                    w = 1;
                }
                if (h < 1)
                {
                    h = 1;
                }
            }
            return(sfc.ToArray());
        }
コード例 #35
0
ファイル: GetDDSArray.cs プロジェクト: NFSTools/GlobalLib
        /// <summary>
        /// Gets .dds texture data along with the .dds header.
        /// </summary>
        /// <returns>.dds texture as a byte array.</returns>
        public override unsafe byte[] GetDDSArray()
        {
            byte[] data;
            if (this._compression == EAComp.P8_08)
            {
                data = new byte[this.Size * 4 + 0x80];
                var copy = Palette.P8toRGBA(this.Data);
                Buffer.BlockCopy(copy, 0, data, 0x80, copy.Length);
            }
            else
            {
                data = new byte[this.Data.Length + 0x80];
                Buffer.BlockCopy(this.Data, 0, data, 0x80, this.Data.Length);
            }

            // Initialize header first
            var DDSHeader = new DDS_HEADER();

            DDSHeader.dwFlags  = DDS_HEADER_FLAGS.TEXTURE; // add texture definition
            DDSHeader.dwFlags += DDS_HEADER_FLAGS.MIPMAP;  // add mipmap definition
            if (this._compression == EAComp.RGBA_08 || this._compression == EAComp.P8_08)
            {
                DDSHeader.dwFlags += DDS_HEADER_FLAGS.PITCH; // add pitch for uncompressed
            }
            else
            {
                DDSHeader.dwFlags += DDS_HEADER_FLAGS.LINEARSIZE; // add linearsize for compressed
            }
            DDSHeader.dwHeight = (uint)this.Height;
            DDSHeader.dwWidth  = (uint)this.Width;

            DDSHeader.dwDepth       = 1; // considering it is not a cubic texture
            DDSHeader.dwMipMapCount = (uint)this.Mipmaps;

            Comp.GetPixelFormat(ref DDSHeader.ddspf, this._compression);
            DDSHeader.dwCaps  = DDSCAPS.SURFACE_FLAGS_TEXTURE; // by default is a texture
            DDSHeader.dwCaps += DDSCAPS.SURFACE_FLAGS_MIPMAP;  // mipmaps should be included
            DDSHeader.dwPitchOrLinearSize = Comp.PitchLinearSize(this._compression, this.Width, this.Height, DDSHeader.ddspf.dwRGBBitCount);

            // Write header using ptr
            fixed(byte *byteptr_t = &data[0])
            {
                *(uint *)(byteptr_t + 0)    = DDS_MAIN.MAGIC;
                *(uint *)(byteptr_t + 4)    = DDSHeader.dwSize;
                *(uint *)(byteptr_t + 8)    = DDSHeader.dwFlags;
                *(uint *)(byteptr_t + 0xC)  = DDSHeader.dwHeight;
                *(uint *)(byteptr_t + 0x10) = DDSHeader.dwWidth;
                *(uint *)(byteptr_t + 0x14) = DDSHeader.dwPitchOrLinearSize;
                *(uint *)(byteptr_t + 0x18) = DDSHeader.dwDepth;
                *(uint *)(byteptr_t + 0x1C) = DDSHeader.dwMipMapCount;
                for (int a1 = 0; a1 < 11; ++a1)
                {
                    *(uint *)(byteptr_t + 0x20 + a1 * 4) = DDSHeader.dwReserved1[a1];
                }
                *(uint *)(byteptr_t + 0x4C) = DDSHeader.ddspf.dwSize;
                *(uint *)(byteptr_t + 0x50) = DDSHeader.ddspf.dwFlags;
                *(uint *)(byteptr_t + 0x54) = DDSHeader.ddspf.dwFourCC;
                *(uint *)(byteptr_t + 0x58) = DDSHeader.ddspf.dwRGBBitCount;
                *(uint *)(byteptr_t + 0x5C) = DDSHeader.ddspf.dwRBitMask;
                *(uint *)(byteptr_t + 0x60) = DDSHeader.ddspf.dwGBitMask;
                *(uint *)(byteptr_t + 0x64) = DDSHeader.ddspf.dwBBitMask;
                *(uint *)(byteptr_t + 0x68) = DDSHeader.ddspf.dwABitMask;
                *(uint *)(byteptr_t + 0x6C) = DDSHeader.dwCaps;
                *(uint *)(byteptr_t + 0x70) = DDSHeader.dwCaps2;
                *(uint *)(byteptr_t + 0x74) = DDSHeader.dwCaps3;
                *(uint *)(byteptr_t + 0x78) = DDSHeader.dwCaps4;
                *(uint *)(byteptr_t + 0x7C) = DDSHeader.dwReserved2;
            }

            return(data);
        }
コード例 #36
0
ファイル: DDSExporter.cs プロジェクト: akintos/UnityAssetLib
        internal static string ExportDDSTexture(Texture2D texture, string directory, bool overwrite = false)
        {
            if (texture.Format != TextureFormat.Alpha8 &&
                texture.Format != TextureFormat.ARGB4444 &&
                texture.Format != TextureFormat.RGB24 &&
                texture.Format != TextureFormat.RGBA32 &&
                texture.Format != TextureFormat.ARGB32 &&
                texture.Format != TextureFormat.RGB565 &&
                texture.Format != TextureFormat.R16 &&
                texture.Format != TextureFormat.DXT1 &&
                texture.Format != TextureFormat.DXT5 &&
                texture.Format != TextureFormat.RGBA4444 &&
                texture.Format != TextureFormat.BGRA32 &&
                texture.Format != TextureFormat.RG16 &&
                texture.Format != TextureFormat.R8)
            {
                throw new UnsupportedFormatException($"Cannot export {texture.Format.ToString()} to DDS format.");
            }

            string exportPath = Path.Combine(directory, $"{texture.m_Name}.dds");

            if (File.Exists(exportPath) && !overwrite)
            {
                throw new IOException($"File {exportPath} already exist and overwrite argument is not set true.");
            }

            byte[] textureData = Texture2DExporter.GetTextureData(texture);

            DDS_HEADER ddsHeader = new DDS_HEADER()
            {
                dwSize              = 0x7C,
                dwFlags             = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT,
                dwHeight            = (uint)texture.m_Height,
                dwWidth             = (uint)texture.m_Width,
                dwPitchOrLinearSize = (uint)texture.m_CompleteImageSize,
                dwDepth             = 0,
                dwMipMapCount       = (uint)texture.m_MipCount,
                dwReserved          = DDS_GENERATOR_DATA,
                dwCaps              = DDSCAPS_TEXTURE,
                dwCaps2             = 0,
                dwCaps3             = 0,
                dwCaps4             = 0,
                dwReserved2         = 0,
            };

            DDS_PIXELFORMAT ddspf = new DDS_PIXELFORMAT()
            {
                dwSize        = 0x20,
                dwFlags       = 0,
                dwFourCC      = 0,
                dwRGBBitCount = 0,
                dwRBitMask    = 0,
                dwGBitMask    = 0,
                dwBBitMask    = 0,
                dwABitMask    = 0,
            };

            if (texture.HasMips)
            {
                ddsHeader.dwFlags |= DDSD_MIPMAPCOUNT;
                ddsHeader.dwCaps  |= DDSCAPS_MIPMAP;
            }

            int blocksize = 0;

            switch (texture.Format)
            {
            case TextureFormat.Alpha8:
            {
                ddsHeader.dwFlags  |= DDSD_PITCH;
                ddspf.dwFlags       = DDPF_ALPHAPIXELS;
                ddspf.dwRGBBitCount = 0x8;
                ddspf.dwABitMask    = 0xF;
                blocksize           = 8;
                break;
            }

            case TextureFormat.ARGB4444:
            {
                ddsHeader.dwFlags  |= DDSD_PITCH;
                ddspf.dwFlags       = DDPF_ALPHAPIXELS | DDPF_RGB;
                ddspf.dwRGBBitCount = 0x10;
                ddspf.dwRBitMask    = 0xFu << 8;
                ddspf.dwGBitMask    = 0xFu << 4;
                ddspf.dwBBitMask    = 0xFu;
                ddspf.dwABitMask    = 0xFu << 12;
                blocksize           = 16;
                break;
            }

            case TextureFormat.RGB24:
            {
                ddsHeader.dwFlags  |= DDSD_PITCH;
                ddspf.dwFlags       = DDPF_RGB;
                ddspf.dwRGBBitCount = 0x18;
                ddspf.dwRBitMask    = 0xFFu << 16;
                ddspf.dwGBitMask    = 0xFFu << 8;
                ddspf.dwBBitMask    = 0xFFu;
                blocksize           = 24;
                break;
            }

            case TextureFormat.RGBA32:
            {
                ddsHeader.dwFlags  |= DDSD_PITCH;
                ddspf.dwFlags       = DDPF_ALPHAPIXELS | DDPF_RGB;
                ddspf.dwRGBBitCount = 0x20;
                ddspf.dwRBitMask    = 0xFFu << 24;
                ddspf.dwGBitMask    = 0xFFu << 16;
                ddspf.dwBBitMask    = 0xFFu << 8;
                ddspf.dwABitMask    = 0xFFu;
                blocksize           = 32;
                break;
            }

            case TextureFormat.ARGB32:
            {
                ddsHeader.dwFlags  |= DDSD_PITCH;
                ddspf.dwFlags       = DDPF_ALPHAPIXELS | DDPF_RGB;
                ddspf.dwRGBBitCount = 0x20;
                ddspf.dwRBitMask    = 0xFFu << 16;
                ddspf.dwGBitMask    = 0xFFu << 8;
                ddspf.dwBBitMask    = 0xFFu;
                ddspf.dwABitMask    = 0xFFu << 24;
                blocksize           = 32;
                break;
            }

            case TextureFormat.RGB565:
            {
                ddsHeader.dwFlags  |= DDSD_PITCH;
                ddspf.dwFlags       = DDPF_RGB;
                ddspf.dwRGBBitCount = 0x10;
                ddspf.dwRBitMask    = 0b1111_1000_0000_0000;
                ddspf.dwGBitMask    = 0b0000_0111_1110_0000;
                ddspf.dwBBitMask    = 0b0000_0000_0001_1111;
                blocksize           = 16;
                break;
            }

            case TextureFormat.R16:
            {
                ddsHeader.dwFlags  |= DDSD_PITCH;
                ddspf.dwFlags       = DDPF_RGB;
                ddspf.dwRGBBitCount = 0x10;
                ddspf.dwRBitMask    = 0xFFFF;
                blocksize           = 16;
                break;
            }

            case TextureFormat.DXT1:
            {
                ddsHeader.dwFlags |= DDSD_LINEARSIZE;
                ddspf.dwFlags      = DDPF_FOURCC;
                ddspf.dwFourCC     = 0x31545844;     // DXT1
                blocksize          = 16;
                break;
            }

            case TextureFormat.DXT5:
            {
                ddsHeader.dwFlags |= DDSD_LINEARSIZE;
                ddspf.dwFlags      = DDPF_FOURCC;
                ddspf.dwFourCC     = 0x35545844;     // DXT5
                break;
            }

            case TextureFormat.RGBA4444:
            {
                ddsHeader.dwFlags  |= DDSD_PITCH;
                ddspf.dwFlags       = DDPF_ALPHAPIXELS | DDPF_RGB;
                ddspf.dwRGBBitCount = 0x10;
                ddspf.dwRBitMask    = 0xFu << 12;
                ddspf.dwGBitMask    = 0xFu << 8;
                ddspf.dwBBitMask    = 0xFu << 4;
                ddspf.dwABitMask    = 0xFu;
                break;
            }

            case TextureFormat.BGRA32:
            {
                ddsHeader.dwFlags  |= DDSD_PITCH;
                ddspf.dwFlags       = DDPF_ALPHAPIXELS | DDPF_RGB;
                ddspf.dwRGBBitCount = 0x20;
                ddspf.dwRBitMask    = 0xFFu << 8;
                ddspf.dwGBitMask    = 0xFFu << 16;
                ddspf.dwBBitMask    = 0xFFu << 24;
                ddspf.dwABitMask    = 0xFFu;
                break;
            }

            case TextureFormat.RG16:
            {
                ddsHeader.dwFlags  |= DDSD_PITCH;
                ddspf.dwFlags       = DDPF_RGB;
                ddspf.dwRGBBitCount = 0x10;
                ddspf.dwRBitMask    = 0xFF00;
                ddspf.dwGBitMask    = 0x00FF;
                break;
            }

            case TextureFormat.R8:
            {
                ddsHeader.dwFlags  |= DDSD_PITCH;
                ddspf.dwFlags       = DDPF_RGB;
                ddspf.dwRGBBitCount = 0x8;
                ddspf.dwRBitMask    = 0xF;
                break;
            }

            default:
                throw new UnsupportedFormatException($"Cannot export {texture.Format} to DDS format.");
            }

            ddsHeader.ddspf = ddspf;

            using (var writer = new BinaryWriter(File.OpenWrite(exportPath)))
            {
                writer.Write(0x20534444u); // 'DDS '
                writer.Write(ddsHeader.dwSize);
                writer.Write(ddsHeader.dwFlags);
                writer.Write(ddsHeader.dwHeight);
                writer.Write(ddsHeader.dwWidth);
                writer.Write(ddsHeader.dwPitchOrLinearSize);
                writer.Write(ddsHeader.dwDepth);
                writer.Write(ddsHeader.dwMipMapCount);
                for (int i = 0; i < ddsHeader.dwReserved.Length; i++)
                {
                    writer.Write(ddsHeader.dwReserved[i]);
                }
                writer.Write(ddsHeader.ddspf.dwSize);
                writer.Write(ddsHeader.ddspf.dwFlags);
                writer.Write(ddsHeader.ddspf.dwFourCC);
                writer.Write(ddsHeader.ddspf.dwRGBBitCount);
                writer.Write(ddsHeader.ddspf.dwRBitMask);
                writer.Write(ddsHeader.ddspf.dwGBitMask);
                writer.Write(ddsHeader.ddspf.dwBBitMask);
                writer.Write(ddsHeader.ddspf.dwABitMask);
                writer.Write(ddsHeader.dwCaps);
                writer.Write(ddsHeader.dwCaps2);
                writer.Write(ddsHeader.dwCaps3);
                writer.Write(ddsHeader.dwCaps4);
                writer.Write(ddsHeader.dwReserved2);
                writer.Write(textureData);
            }

            return(exportPath);
        }