Beispiel #1
0
        public uint[] Reserved2; // [3]

        public DdsHeader()
        {
            Size        = 124; // (9 * 4) + (8 * 4) + (14 * 4)
            Reserved1   = new uint[11];
            PixelFormat = new DdsPixelFormat();
            Reserved2   = new uint[3];
        }
Beispiel #2
0
        public static DdsFile ConvertToDds(FtexFile file)
        {
            DdsFile result = new DdsFile
            {
                Header = new DdsFileHeader
                {
                    Size        = DdsFileHeader.DefaultHeaderSize,
                    Flags       = DdsFileHeaderFlags.Texture,
                    Height      = file.Height,
                    Width       = file.Width,
                    Depth       = file.Depth,
                    MipMapCount = file.MipMapCount,
                    Caps        = DdsSurfaceFlags.Texture
                }
            };

            if (result.Header.Depth == 1)
            {
                result.Header.Depth = 0;
            }
            else if (result.Header.Depth > 1)
            {
                result.Header.Flags |= DdsFileHeaderFlags.Volume;
            }

            if (result.Header.MipMapCount == 1)
            {
                result.Header.MipMapCount = 0;
            }
            else if (result.Header.MipMapCount > 1)
            {
                result.Header.Flags |= DdsFileHeaderFlags.MipMap;
                result.Header.Caps  |= DdsSurfaceFlags.MipMap;
            }

            switch (file.PixelFormatType)
            {
            case 0:
                result.Header.PixelFormat = DdsPixelFormat.DdsPfA8R8G8B8();
                break;

            case 1:
                result.Header.PixelFormat = DdsPixelFormat.DdsLuminance();
                break;

            case 2:
                result.Header.PixelFormat = DdsPixelFormat.DdsPfDxt1();
                break;

            case 4:
                result.Header.PixelFormat = DdsPixelFormat.DdsPfDxt5();
                break;

            default:
                throw new ArgumentException($"Unknown PixelFormatType {file.PixelFormatType}");
            }

            result.Data = file.Data;
            return(result);
        }
Beispiel #3
0
        private MipMap[] ThirtyTwoBitImageFormat(Stream stream, int width, int height, int count)
        {
            DdsPixelFormat pixelFormat = this.DdsHeader.PixelFormat;

            bool hasAlpha = pixelFormat.Flags.HasFlag(DdsPixelFormatFlags.AlphaPixels);

            if (hasAlpha && pixelFormat.RBitMask == 0xFF0000 && pixelFormat.GBitMask == 0xFF00 && pixelFormat.BBitMask == 0xFF)
            {
                return(this.AllocateMipMaps <Bgra32>(stream, width, height, count));
            }

            if (hasAlpha && pixelFormat.RBitMask == 0xFF && pixelFormat.GBitMask == 0xFF00 && pixelFormat.BBitMask == 0xFF0000)
            {
                return(this.AllocateMipMaps <Rgba32>(stream, width, height, count));
            }

            if (!hasAlpha && pixelFormat.RBitMask == 0xFF0000 && pixelFormat.GBitMask == 0xFF00 && pixelFormat.BBitMask == 0xFF)
            {
                return(this.AllocateMipMaps <Bgr32>(stream, width, height, count));
            }

            if (!hasAlpha && pixelFormat.RBitMask == 0xFF && pixelFormat.GBitMask == 0xFF00 && pixelFormat.BBitMask == 0xFF0000)
            {
                return(this.AllocateMipMaps <Rgb32>(stream, width, height, count));
            }

            if (!hasAlpha && pixelFormat.RBitMask == 0xFFFF && pixelFormat.GBitMask == 0xFFFF0000 && pixelFormat.BBitMask == 0x0)
            {
                return(this.AllocateMipMaps <Rg32>(stream, width, height, count));
            }

            //R11G11B10_Float

            throw new Exception($"Unsupported 32 bit format");
        }
        private Stream buildDdsImage(int mipMapIndex, out FileFormat imageFormat)
        {
            DomainPropertyByteValue formatProp = PropertyHeader.GetProperty("Format").FirstOrDefault()?.Value as DomainPropertyByteValue;

            imageFormat = FileFormat.Unknown;

            if (formatProp == null)
            {
                return(null);
            }

            string format = formatProp.PropertyString;

            DomainMipMap mipMap = MipMaps[mipMapIndex];

            imageFormat = DdsPixelFormat.ParseFileFormat(format);

            DdsHeader ddsHeader = new DdsHeader(new DdsSaveConfig(imageFormat, 0, 0, false, false), mipMap.Width, mipMap.Height);

            MemoryStream stream = new MemoryStream();

            BinaryWriter writer = new BinaryWriter(stream);

            ddsHeader.Write(writer);

            stream.Write(mipMap.ImageData, 0, mipMap.ImageData.Length);

            stream.Flush();

            stream.Position = 0;

            return(stream);
        }
Beispiel #5
0
        private static List <byte[]> GetMipMapData(DdsFile file)
        {
            const int     minimumWidth  = 4;
            const int     minimumHeight = 4;
            List <byte[]> mipMapDatas   = new List <byte[]>();

            byte[] data         = file.Data;
            int    dataOffset   = 0;
            int    width        = file.Header.Width;
            int    height       = file.Header.Height;
            int    depth        = file.Header.Depth == 0 ? 1 : file.Header.Depth;
            int    mipMapsCount = file.Header.Flags.HasFlag(DdsFileHeaderFlags.MipMap) ? file.Header.MipMapCount : 1;

            for (int i = 0; i < mipMapsCount; i++)
            {
                int size   = DdsPixelFormat.CalculateImageSize(file.Header.PixelFormat, width, height, depth);
                var buffer = new byte[size];
                Array.Copy(data, dataOffset, buffer, 0, size);
                mipMapDatas.Add(buffer);
                dataOffset += size;
                width       = Math.Max(width / 2, minimumWidth);
                height      = Math.Max(height / 2, minimumHeight);
            }
            return(mipMapDatas);
        }
Beispiel #6
0
        public static TxpMipMap FromDds(DdsMipMap mip, DdsPixelFormat pf)
        {
            TxpMipMap tex = new TxpMipMap();

            if (mip == null)
            {
                return(tex);
            }
            tex.width  = mip.width;
            tex.height = mip.height;
            switch (new string(pf.compressionName))
            {
            case "RGB ": tex.type = TexType.RGB; break;

            case "RGBA": tex.type = TexType.RGBA; break;

            case "DXT1": tex.type = TexType.DXT1; break;

            case "DXT3": tex.type = TexType.DXT3; break;

            case "DXT5": tex.type = TexType.DXT5; break;

            case "ATI2": tex.type = TexType.ATI2n; break;
            }
            tex.byteSize = mip.byteSize;
            tex.data     = mip.data;
            return(tex);
        }
Beispiel #7
0
        public void TestPfA8R8G8B8()
        {
            DdsTestCase[] testCases =
            {
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(), 1024, 1024,  1), "A8R8G8B8 1 mip"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(), 1024, 1024,  2), "A8R8G8B8 2 mip"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(), 1024, 1024,  5), "A8R8G8B8 5 mip"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(), 1024, 1024, 10), "A8R8G8B8 10 mip"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(), 1024, 1024, 15), "A8R8G8B8 15 mip"),

                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(),    1,    1,  1), "A8R8G8B8 1x1"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(),    2,    2,  2), "A8R8G8B8 2x2"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(),    4,    4,  3), "A8R8G8B8 4x4"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(),    8,    8,  4), "A8R8G8B8 8x8"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(),   16,   16,  5), "A8R8G8B8 16x16"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(),   32,   32,  6), "A8R8G8B8 32x32"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(),   64,   64,  7), "A8R8G8B8 64x63"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(),  128,  128,  8), "A8R8G8B8 128x128"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(),  256,  256,  9), "A8R8G8B8 256x256"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(),  512,  512, 10), "A8R8G8B8 512x512"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(), 1024, 1024, 11), "A8R8G8B8 1024x1024"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(), 2048, 2048, 12), "A8R8G8B8 2048x2048"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(), 4096, 4096, 13), "A8R8G8B8 4096x4096"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfA8R8G8B8(), 8192, 8192, 14), "A8R8G8B8 8192x8192")
            };

            RunDdsTestCase(testCases);
        }
Beispiel #8
0
        static SurfaceFormat GetSurfaceFormat(ref DdsPixelFormat pixelFormat, out bool rbSwap)
        {
            rbSwap = false;
            if (pixelFormat.dwFlags.HasFlag(Ddpf.FourCC))
            {
                // It is a compressed format
                switch (pixelFormat.dwFourCC)
                {
                case FourCC.Dxt1:
                    return(SurfaceFormat.Dxt1);

                case FourCC.Dxt2:
                    throw new ContentLoadException("Unsupported compression format DXT2");

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

                case FourCC.Dxt4:
                    throw new ContentLoadException("Unsupported compression format DXT4");

                case FourCC.Dxt5:
                    return(SurfaceFormat.Dxt5);
                }
            }
            else if (pixelFormat.dwFlags.HasFlag(Ddpf.Rgb))
            {
                // Uncompressed format
                if (pixelFormat.dwFlags.HasFlag(Ddpf.AlphaPixels))
                {
                    // Format contains RGB and A
                    if (pixelFormat.dwRgbBitCount == 16)
                    {
                        if (pixelFormat.dwABitMask == 0xF)
                        {
                            rbSwap = pixelFormat.dwBBitMask == 0xF0;
                            return(SurfaceFormat.Bgra4444);
                        }
                        rbSwap = pixelFormat.dwBBitMask == 0x3E;
                        return(SurfaceFormat.Bgra5551);
                    }
                    else if (pixelFormat.dwRgbBitCount == 32)
                    {
                        rbSwap = pixelFormat.dwBBitMask == 0xFF00;
                        return(SurfaceFormat.Color);
                    }
                    throw new ContentLoadException("Unsupported RGBA pixel format");
                }
                else
                {
                    // Format contains RGB only
                    if (pixelFormat.dwRgbBitCount == 16)
                    {
                        rbSwap = pixelFormat.dwBBitMask == 0x1F;
                        return(SurfaceFormat.Bgr565);
                    }
                    throw new ContentLoadException("Unsupported RGB pixel format");
                }
            }
            throw new ContentLoadException("Unsupported pixel format");
        }
Beispiel #9
0
        public void TestLuminance()
        {
            DdsTestCase[] testCases =
            {
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(), 1024, 1024,  1), "Luminance 1 mip"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(), 1024, 1024,  2), "Luminance 2 mip"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(), 1024, 1024,  5), "Luminance 5 mip"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(), 1024, 1024, 10), "Luminance 10 mip"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(), 1024, 1024, 15), "Luminance 15 mip"),

                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(),    1,    1,  1), "Luminance 1x1"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(),    2,    2,  2), "Luminance 2x2"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(),    4,    4,  3), "Luminance 4x4"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(),    8,    8,  4), "Luminance 8x8"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(),   16,   16,  5), "Luminance 16x16"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(),   32,   32,  6), "Luminance 32x32"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(),   64,   64,  7), "Luminance 64x63"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(),  128,  128,  8), "Luminance 128x128"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(),  256,  256,  9), "Luminance 256x256"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(),  512,  512, 10), "Luminance 512x512"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(), 1024, 1024, 11), "Luminance 1024x1024"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(), 2048, 2048, 12), "Luminance 2048x2048"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(), 4096, 4096, 13), "Luminance 4096x4096"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsLuminance(), 8192, 8192, 14), "Luminance 8192x8192")
            };

            RunDdsTestCase(testCases);
        }
Beispiel #10
0
        public void TestDxt5()
        {
            DdsTestCase[] testCases =
            {
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(), 1024, 1024,  1), "dxt5 1 mip"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(), 1024, 1024,  2), "dxt5 2 mip"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(), 1024, 1024,  5), "dxt5 5 mip"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(), 1024, 1024, 10), "dxt5 10 mip"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(), 1024, 1024, 15), "dxt5 15 mip"),

                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(),    1,    1,  1), "dxt1 1x1"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(),    2,    2,  2), "dxt1 2x2"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(),    4,    4,  3), "dxt1 4x4"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(),    8,    8,  4), "dxt1 8x8"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(),   16,   16,  5), "dxt1 16x16"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(),   32,   32,  6), "dxt1 32x32"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(),   64,   64,  7), "dxt1 64x63"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(),  128,  128,  8), "dxt1 128x128"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(),  256,  256,  9), "dxt1 256x256"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(),  512,  512, 10), "dxt1 512x512"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(), 1024, 1024, 11), "dxt1 1024x1024"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(), 2048, 2048, 12), "dxt1 2048x2048"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(), 4096, 4096, 13), "dxt1 4096x4096"),
                new DdsTestCase(new DdsOptions(DdsPixelFormat.DdsPfDxt5(), 8192, 8192, 14), "dxt1 8192x8192"),
            };

            RunDdsTestCase(testCases);
        }
Beispiel #11
0
 public DdsOptions(DdsPixelFormat pixelFormat, short width, short height, short depth, short mipMapCount)
 {
     PixelFormat = pixelFormat;
     Width       = width;
     Height      = height;
     Depth       = depth;
     MipMapCount = mipMapCount;
 }
Beispiel #12
0
        private static DdsFile GenerateDds(DdsOptions options)
        {
            DdsFile ddsFile = new DdsFile();

            ddsFile.Header = new DdsFileHeader
            {
                Size        = DdsFileHeader.DefaultHeaderSize,
                Flags       = DdsFileHeaderFlags.Texture,
                Width       = options.Width,
                Height      = options.Height,
                Depth       = options.Depth,
                MipMapCount = options.MipMapCount,
                Caps        = DdsSurfaceFlags.Texture,
                PixelFormat = options.PixelFormat
            };

            if (ddsFile.Header.Depth > 1)
            {
                ddsFile.Header.Flags |= DdsFileHeaderFlags.Volume;
            }

            int mipMapCount = ddsFile.Header.MipMapCount;

            if (ddsFile.Header.MipMapCount == 1)
            {
                ddsFile.Header.MipMapCount = 0;
            }
            else if (ddsFile.Header.MipMapCount > 1)
            {
                ddsFile.Header.Flags |= DdsFileHeaderFlags.MipMap;
                ddsFile.Header.Caps  |= DdsSurfaceFlags.MipMap;
            }

            const int minimumWidth     = 4;
            const int minimumHeight    = 4;
            int       mipMapHeight     = ddsFile.Header.Height;
            int       mipMapWidth      = ddsFile.Header.Width;
            int       mipMapDepth      = ddsFile.Header.Depth == 0 ? 1 : ddsFile.Header.Depth;
            int       mipMapBufferSize = 0;

            for (int i = 0; i < mipMapCount; i++)
            {
                int mipMapSize = DdsPixelFormat.CalculateImageSize(ddsFile.Header.PixelFormat, mipMapWidth, mipMapHeight, mipMapDepth);
                mipMapBufferSize += mipMapSize;
                mipMapWidth       = Math.Max(mipMapWidth / 2, minimumWidth);
                mipMapHeight      = Math.Max(mipMapHeight / 2, minimumHeight);
            }

            ddsFile.Data = new byte[mipMapBufferSize];
            for (int i = 0; i < mipMapBufferSize; i++)
            {
                ddsFile.Data[i] = (byte)(i % 0xFF);
            }


            return(ddsFile);
        }
Beispiel #13
0
 private static void ReadPixelFormat(BinaryReader reader, ref DdsPixelFormat pixel_format)
 {
     pixel_format.size          = reader.ReadUInt32();
     pixel_format.flags         = (DdsPixelFormatFlags)(reader.ReadUInt32());
     pixel_format.four_cc       = reader.ReadBytes(4);
     pixel_format.rgb_bit_count = reader.ReadUInt32();
     pixel_format.r_bit_mask    = reader.ReadUInt32();
     pixel_format.g_bit_mask    = reader.ReadUInt32();
     pixel_format.b_bit_mask    = reader.ReadUInt32();
     pixel_format.a_bit_mask    = reader.ReadUInt32();
 }
Beispiel #14
0
        public static Span <byte> Create(TextureFormat format,
                                         Caps capabilities,
                                         Caps2 capabilities2,
                                         int width, int height,
                                         int?depth, int?mipMapCount,
                                         int?pitch, int?linearSize)
        {
            Span <byte> data = new byte[128];

            data.WriteInt32At(0, Magic);
            data.WriteInt32At(4, Length - 4); // Remove 4 from length for magic size
            var flags = DefaultFlags;

            if (depth.HasValue)
            {
                flags |= DdsFlags.Depth;
            }
            if (mipMapCount.HasValue)
            {
                flags |= DdsFlags.MipMapCount;
            }
            if (pitch.HasValue)
            {
                flags |= DdsFlags.Pitch;
            }
            if (linearSize.HasValue)
            {
                flags |= DdsFlags.LinearSize;
            }

            data.WriteInt32At(8, (int)flags);
            data.WriteInt32At(12, height);
            data.WriteInt32At(16, width);
            data.WriteInt32At(20, (pitch ?? linearSize).GetValueOrDefault());
            data.WriteInt32At(24, depth.GetValueOrDefault());
            data.WriteInt32At(28, mipMapCount.GetValueOrDefault() == 0 ? 1 : mipMapCount.GetValueOrDefault());

            // 44 bytes of reserved space

            DdsPixelFormat.Write(format, data.Slice(76));

            if (flags.HasFlag(DdsFlags.MipMapCount))
            {
                capabilities |= Caps.MipMap;
            }
            data.WriteInt32At(108, (int)capabilities);
            data.WriteInt32At(112, (int)capabilities2);
            data.WriteInt32At(116, 0); // Caps3 (unused)
            data.WriteInt32At(120, 0); // Caps4 (unused)
            data.WriteInt32At(124, 0); // Reserved

            return(data);
        }
Beispiel #15
0
        public FileFormat GetFormat()
        {
            GpkByteProperty formatProp = objectExport.GetProperty("Format") as GpkByteProperty;

            if (formatProp == null)
            {
                return(FileFormat.Unknown);
            }

            string format = formatProp.nameValue;

            return(DdsPixelFormat.ParseFileFormat(format));
        }
Beispiel #16
0
        private MipMap[] TwentyFourBitImageFormat(Stream stream, int width, int height, int count)
        {
            DdsPixelFormat pixelFormat = this.DdsHeader.PixelFormat;

            bool hasAlpha = pixelFormat.Flags.HasFlag(DdsPixelFormatFlags.AlphaPixels);

            if (!hasAlpha && pixelFormat.RBitMask == 0xFF0000 && pixelFormat.GBitMask == 0xFF00 && pixelFormat.BBitMask == 0xFF)
            {
                this.AllocateMipMaps <Rgb24>(stream, width, height, count);
            }

            throw new Exception($"Unsupported 24 bit format");
        }
Beispiel #17
0
        public void SaveFormat(GpkExport export)
        {
            GpkByteProperty formatProp = export.GetProperty("Format") as GpkByteProperty;

            if (formatProp == null)
            {
                parsedImageFormat = FileFormat.Unknown;
            }
            else
            {
                string format = formatProp.nameValue;
                parsedImageFormat = DdsPixelFormat.ParseFileFormat(format);
            }
        }
Beispiel #18
0
        public DdsHeader(TextureFormat format, TextureType type, int width, int height, int?depth, int?mipMapCount, int?pitch, int?linearSize)
        {
            HeaderData.WriteInt32(Magic);
            HeaderData.WriteInt32(Length - 4); // Remove 4 from length for magic size
            var flags = DefaultFlags;

            if (depth.HasValue)
            {
                flags |= DdsFlags.Depth;
            }
            if (mipMapCount.HasValue)
            {
                flags |= DdsFlags.MipMapCount;
            }
            if (pitch.HasValue)
            {
                flags |= DdsFlags.Pitch;
            }
            if (linearSize.HasValue)
            {
                flags |= DdsFlags.LinearSize;
            }

            HeaderData.WriteInt32((int)flags);
            HeaderData.WriteInt32(height);
            HeaderData.WriteInt32(width);
            HeaderData.WriteInt32((pitch ?? linearSize).GetValueOrDefault());
            HeaderData.WriteInt32(depth.GetValueOrDefault());
            HeaderData.WriteInt32(mipMapCount.GetValueOrDefault() == 0 ? 1 : mipMapCount.GetValueOrDefault());
            HeaderData.Write(new byte[44], 0, 44);

            var pixelFormat = new DdsPixelFormat(format);

            pixelFormat.Data.CopyTo(HeaderData);

            var caps = CapsLookup[type];

            if (flags.HasFlag(DdsFlags.MipMapCount))
            {
                caps |= Caps.MipMap;
            }
            HeaderData.WriteInt32((int)caps);
            HeaderData.WriteInt32((int)Caps2Lookup[type]);
            HeaderData.WriteInt32(0); // Caps3 (unused)
            HeaderData.WriteInt32(0); // Caps4 (unused)
            HeaderData.WriteInt32(0); // Reserved

            HeaderData.Seek(0, SeekOrigin.Begin);
        }
Beispiel #19
0
        public static FtexFile ConvertToFtex(DdsFile file, FtexTextureType textureType, FtexUnknownFlags flags, int?ftexsFileCount)
        {
            FtexFile result = new FtexFile();

            if (file.Header.PixelFormat.Equals(DdsPixelFormat.DdsPfA8R8G8B8()))
            {
                result.PixelFormatType = 0;
            }
            else if (file.Header.PixelFormat.Equals(DdsPixelFormat.DdsLuminance()))
            {
                result.PixelFormatType = 1;
            }
            else if (file.Header.PixelFormat.Equals(DdsPixelFormat.DdsPfDxt1()))
            {
                result.PixelFormatType = 2;
            }
            else if (file.Header.PixelFormat.Equals(DdsPixelFormat.DdsPfDxt3()) ||
                     file.Header.PixelFormat.Equals(DdsPixelFormat.DdsPfDxt5()))
            {
                result.PixelFormatType = 4;
            }
            else
            {
                throw new ArgumentException($"Unknown PixelFormatType {file.Header.PixelFormat}");
            }

            result.Height = Convert.ToInt16(file.Header.Height);
            result.Width  = Convert.ToInt16(file.Header.Width);
            result.Depth  = Convert.ToInt16(file.Header.Depth == 0 ? 1 : file.Header.Depth);

            var mipMapData = GetMipMapData(file);
            var mipMaps    = GetMipMapInfos(mipMapData, ftexsFileCount);
            var ftexsFiles = GetFtexsFiles(mipMaps, mipMapData);

            result.MipMapCount = Convert.ToByte(mipMaps.Count);
            result.NrtFlag     = 2;
            result.AddMipMapInfos(mipMaps);
            result.AddFtexsFiles(ftexsFiles);
            result.FtexsFileCount = ftexsFileCount == 0
                ? (byte)0
                : Convert.ToByte(ftexsFiles.Count);
            result.AdditionalFtexsFileCount = ftexsFileCount == 0
                ? (byte)0
                : Convert.ToByte(ftexsFiles.Count - 1);
            result.UnknownFlags = flags;
            result.TextureType  = textureType;
            return(result);
        }
Beispiel #20
0
        private MipMap[] EightBitImageFormat(Stream stream, int width, int height, int count)
        {
            DdsPixelFormat pixelFormat = this.DdsHeader.PixelFormat;

            bool hasAlpha = pixelFormat.Flags.HasFlag(DdsPixelFormatFlags.AlphaPixels);

            if (hasAlpha && pixelFormat.RBitMask == 0x0 && pixelFormat.GBitMask == 0x00 && pixelFormat.BBitMask == 0x00)
            {
                return(this.AllocateMipMaps <A8>(stream, width, height, count));
            }

            if (!hasAlpha && pixelFormat.RBitMask == 0xFF && pixelFormat.GBitMask == 0x00 && pixelFormat.BBitMask == 0x00)
            {
                return(this.AllocateMipMaps <L8>(stream, width, height, count));
            }

            throw new Exception($"Unsupported 8 bit format");
        }
            internal DdsHeader(int width, int height, int arraySize, int mipCount, DdsFileFormat format)
            {
                this.size   = SizeOf;
                this.flags  = HeaderFlags.Texture;
                this.height = (uint)height;
                this.width  = (uint)width;
                switch (format)
                {
                case DdsFileFormat.R8G8B8X8:
                    this.flags            |= HeaderFlags.Pitch;
                    this.pitchOrLinearSize = (((uint)width * 32) + 7) / 8;
                    break;

                case DdsFileFormat.B8G8R8:
                    this.flags            |= HeaderFlags.Pitch;
                    this.pitchOrLinearSize = (((uint)width * 24) + 7) / 8;
                    break;

                default:
                    throw new InvalidOperationException(GetUnsupportedFormatMessage(format));
                }
                this.depth = 1;
                if (mipCount > 1)
                {
                    this.flags      |= HeaderFlags.Mipmap;
                    this.mipMapCount = (uint)mipCount;
                    this.caps       |= SurfaceFlags.Mipmap;
                }
                else
                {
                    this.mipMapCount = 1;
                }
                this.reserved1 = new uint[11];
                this.ddspf     = new DdsPixelFormat(format);
                this.caps     |= SurfaceFlags.Texture;
                if (arraySize == 6)
                {
                    this.caps  |= SurfaceFlags.Cubemap;
                    this.caps2 |= CubemapFaces.All;
                }
                this.caps3     = 0;
                this.caps4     = 0;
                this.reserved2 = 0;
            }
Beispiel #22
0
        public void Write(Stream outputStream)
        {
            if (Data == null)
            {
                return;
            }

            byte[] data = Data;
            if (GameVersion == GameVersion.Bloodborne)
            {
                DxgiFormat     dxgiFormat  = (DxgiFormat)DxgiFormat;
                DdsPixelFormat pixelFormat = DdsPixelFormat.DxgiToDdsPixelFormat(dxgiFormat);
                DdsFile        ddsFile     = new DdsFile
                {
                    Header = new DdsFileHeader
                    {
                        Flags             = DdsFileHeaderFlags.Texture | (MipMapCount > 1 ? DdsFileHeaderFlags.MipMap : 0),
                        Height            = Height,
                        Width             = Width,
                        Depth             = 0,
                        PitchOrLinearSize = Data.Length,
                        MipMapCount       = MipMapCount,
                        PixelFormat       = pixelFormat,
                        Caps = DdsSurfaceFlags.Texture | (MipMapCount > 1 ? DdsSurfaceFlags.MipMap : 0)
                    },
                    HeaderDx10 = pixelFormat.FourCc != DdsPixelFormat.Dx10FourCc
                        ? null
                        : new DdsFileHeaderDx10
                    {
                        Format            = dxgiFormat,
                        ResourceDimension = D3D10ResourceDimension.Texture2D,
                        MiscFlag          = 0,
                        ArraySize         = 1,
                        MiscFlags2        = 0
                    },
                    Data = DdsFile.ConvertData(data, Height, Width, dxgiFormat)
                };
                ddsFile.Write(outputStream);
            }
            else
            {
                outputStream.Write(data, 0, data.Length);
            }
        }
Beispiel #23
0
        private MipMap[] SixteenBitImageFormat(Stream stream, int width, int height, int count)
        {
            DdsPixelFormat pixelFormat = this.DdsHeader.PixelFormat;

            bool hasAlpha = pixelFormat.Flags.HasFlag(DdsPixelFormatFlags.AlphaPixels);

            if (hasAlpha && pixelFormat.RBitMask == 0xF00 && pixelFormat.GBitMask == 0xF0 && pixelFormat.BBitMask == 0xF)
            {
                return(this.AllocateMipMaps <Bgra16>(stream, width, height, count));
            }

            if (!hasAlpha && pixelFormat.RBitMask == 0x7C00 && pixelFormat.GBitMask == 0x3E0 && pixelFormat.BBitMask == 0x1F)
            {
                return(this.AllocateMipMaps <Bgr555>(stream, width, height, count));
            }

            if (hasAlpha && pixelFormat.RBitMask == 0x7C00 && pixelFormat.GBitMask == 0x3E0 && pixelFormat.BBitMask == 0x1F)
            {
                return(this.AllocateMipMaps <Bgra5551>(stream, width, height, count));
            }

            if (!hasAlpha && pixelFormat.RBitMask == 0xF800 && pixelFormat.GBitMask == 0x7E0 && pixelFormat.BBitMask == 0x1F)
            {
                return(this.AllocateMipMaps <Bgr565>(stream, width, height, count));
            }

            if (hasAlpha && pixelFormat.RBitMask == 0xFF && pixelFormat.GBitMask == 0x0 && pixelFormat.BBitMask == 0x0)
            {
                return(this.AllocateMipMaps <La16>(stream, width, height, count));
            }

            if (!hasAlpha && pixelFormat.RBitMask == 0xFF && pixelFormat.GBitMask == 0xFF00 && pixelFormat.BBitMask == 0x0)
            {
                return(this.AllocateMipMaps <Rg16>(stream, width, height, count));
            }

            throw new Exception($"Unsupported 16 bit format");
        }
        private static SurfaceFormat GetSurfaceFormat(ref DdsPixelFormat pixelFormat, out bool rbSwap)
        {
            rbSwap = false;
            if (pixelFormat.dwFlags.HasFlag(Ddpf.FourCC))
            {
                switch (pixelFormat.dwFourCC)
                {
                case FourCC.A32B32G32R32F:
                    return(SurfaceFormat.Vector4);

                case FourCC.Dxt1:
                    return(SurfaceFormat.Dxt1);

                case FourCC.Dxt2:
                    throw new ContentLoadException("Unsupported compression format DXT2");

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

                case FourCC.Dxt4:
                    throw new ContentLoadException("Unsupported compression format DXT4");

                case FourCC.Dxt5:
                    return(SurfaceFormat.Dxt5);
                }
            }
            else if (pixelFormat.dwFlags.HasFlag(Ddpf.Rgb))
            {
                // Uncompressed format
                if (pixelFormat.dwFlags.HasFlag(Ddpf.AlphaPixels))
                {
                    // Format contains RGB and A
                    if (pixelFormat.dwRgbBitCount == 16)
                    {
                        if (pixelFormat.dwABitMask == 0xF)
                        {
                            rbSwap = pixelFormat.dwBBitMask == 0xF0;
                            return(SurfaceFormat.Bgra4444);
                        }
                        rbSwap = pixelFormat.dwBBitMask == 0x3E;
                        return(SurfaceFormat.Bgra5551);
                    }
                    else if (pixelFormat.dwRgbBitCount == 32)
                    {
                        rbSwap = pixelFormat.dwBBitMask == 0xFF;
                        return(SurfaceFormat.Rgba32);
                    }
                    throw new ContentLoadException("Unsupported RGBA pixel format");
                }
                else
                {
                    // Format contains RGB only
                    if (pixelFormat.dwRgbBitCount == 16)
                    {
                        rbSwap = pixelFormat.dwBBitMask == 0x1F;
                        return(SurfaceFormat.Bgr565);
                    }
                    else if (pixelFormat.dwRgbBitCount == 24)
                    {
                        rbSwap = pixelFormat.dwBBitMask == 0xFF;
                        return(SurfaceFormat.Rgba32);
                    }
                    else if (pixelFormat.dwRgbBitCount == 32)
                    {
                        rbSwap = pixelFormat.dwBBitMask == 0xFF;
                        return(SurfaceFormat.Rgba32);
                    }
                    throw new ContentLoadException("Unsupported RGB pixel format");
                }
            }
            //else if (pixelFormat.dwFlags.HasFlag(Ddpf.Luminance))
            //{
            //    return SurfaceFormat.Alpha8;
            //}
            throw new ContentLoadException("Unsupported pixel format");
        }
 private static bool IsBitMask(DdsPixelFormat ddpf, uint r, uint g, uint b, uint a)
 {
     return(ddpf.RedBitMask == r && ddpf.GreenBitMask == g && ddpf.BlueBitMask == b && ddpf.AlphaBitMask == a);
 }
Beispiel #26
0
            public DdsHeader(Stream s)
            {
                BinaryReader r = new BinaryReader(s);

                // -- DWORD dwMagic --

                magic = (DdsMagic)r.ReadUInt32();
                if (!Enum.IsDefined(typeof(DdsMagic), magic))
                    throw new InvalidDataException(String.Format(
                        "DDS Magic Number invalid.  Got 0x{0:X8}, expected 0x{1:X8} ('DDS ').  At 0x{2:X8}."
                        , (uint)magic
                        , (uint)DdsMagic.dds_
                        , s.Position
                        )
                    );

                // -- DDS_HEADER header --

                size = r.ReadUInt32();
                if (size == 0)
                {
                    Console.WriteLine(String.Format(
                        "DDS Header Size is zero, expected 124.  At 0x{0:X8}.  Correcting..."
                        , s.Position
                        ));
                    size = 124;
                }
                else if (size != 124)
                    throw new InvalidDataException(String.Format(
                        "DDS Header Size invalid.  Got {0}, expected 124.  At 0x{1:X8}."
                        , size
                        , s.Position
                        ));

                flags = (DdsFlags)r.ReadUInt32();
                if (((uint)(flags & (writeFlags | DdsFlags.pitch | DdsFlags.linearSize))).Bits() != ((uint)writeFlags).Bits() + 1)
                {
                    Console.WriteLine(String.Format(
                        "DDS Header Flags invalid.  Got {0}, expected {1} and either _pitch or _linearSize.  At 0x{2:X8}.  Correcting..."
                        , flags
                        , writeFlags
                        , s.Position
                        ));
                    flags |= writeFlags;
                    // We can't know yet which is best to pick of _pitch and _linearSize
                }

                height = r.ReadUInt32();
                if (height == 0)
                    throw new InvalidDataException(String.Format(
                        "DDS Height invalid.  Got 0, expected non-zero value.  At 0x{1:X8}"
                        , s.Position
                        )
                    );

                width = r.ReadUInt32();
                if (width == 0)
                    throw new InvalidDataException(String.Format(
                    "DDS Width invalid.  Got 0, expected non-zero value.  At 0x{1:X8}"
                    , s.Position
                    )
                );

                pitchOrLinearSize = r.ReadUInt32();

                depth = r.ReadUInt32();
                if ((flags & DdsFlags.depth) != 0 && depth != 0)
                {
                    Console.WriteLine(String.Format(
                        "Only simple DDS Textures are supported.  This DDS has depth {0}.  At 0x{1:X8}.  Clearing flag and _depth to zero..."
                        , depth
                        , s.Position
                        ));
                    flags &= ~DdsFlags.depth;
                    depth = 0;
                }
                if ((flags & DdsFlags.depth) != 0 || depth != 0)
                {
                    Console.WriteLine(String.Format(
                        "DDS Header invalid.  Inconsistent depth flag ({0}) and _depth ({1}).  At 0x{2:X8}.  Clearing flag and _depth to zero..."
                        , flags & DdsFlags.depth
                        , depth
                        , s.Position
                        ));
                    flags &= ~DdsFlags.depth;
                    depth = 0;
                }

                numMipMaps = r.ReadUInt32();
                if ((flags & DdsFlags.mipMapCount) != 0 && numMipMaps != 1)
                {
                    Console.WriteLine(String.Format(
                        "Only simple DDS Textures are supported.  This DDS has {0} mip maps.  At 0x{1:X8}.  Clearing flag and setting count to one..."
                        , numMipMaps
                        , s.Position
                        ));
                    flags &= ~DdsFlags.mipMapCount;
                    numMipMaps = 1;
                }
                if ((flags & DdsFlags.mipMapCount) != 0 || numMipMaps == 0)
                {
                    Console.WriteLine(String.Format(
                        "DDS Header invalid.  Inconsistent mipMapCount flag ({0}) and _numMipMaps ({1}).  At 0x{2:X8}.  Clearing flag and setting count to one..."
                        , flags & DdsFlags.mipMapCount
                        , numMipMaps
                        , s.Position
                        ));
                    flags &= ~DdsFlags.mipMapCount;
                    numMipMaps = 1;
                }

                for (int i = 0; i < reserved1.Length; i++) reserved1[i] = r.ReadUInt32();
                for (int i = 0; i < reserved1.Length; i++) reserved1[i] = 0;

                pixelFormat = new DdsPixelFormat(s);

                var mask = (pixelFormat.FourCC == 0) ? DdsFlags.pitch : DdsFlags.linearSize;
                var notMask = (pixelFormat.FourCC != 0) ? DdsFlags.pitch : DdsFlags.linearSize;
                if ((flags & mask) == 0)
                {
                    Console.WriteLine(String.Format(
                        "DDS Header Flags invalid.  {0} not set.  At 0x{1:X8}.  Correcting..."
                        , mask
                        , s.Position
                        ));
                    flags &= ~notMask;
                    flags |= mask;
                }

                surfaceCaps = (DdsSurfaceCaps)r.ReadUInt32();
                if ((surfaceCaps & ~DdsSurfaceCaps.texture) != 0)
                {
                    Console.WriteLine(String.Format(
                        "Only simple DDS Textures are supported.  This DDS has other surface capabilities: {0}.  At 0x{1:X8}.  Clearing unsupported capabilities..."
                        , surfaceCaps
                        , s.Position
                        ));
                    surfaceCaps &= DdsSurfaceCaps.texture;
                }
                if (surfaceCaps == 0)
                {
                    Console.WriteLine(String.Format(
                        "DDS Header Surface Caps invalid.  Got zero, expected texture.  At 0x{0:X8}.  Correcting..."
                        , s.Position
                        ));
                    surfaceCaps |= DdsSurfaceCaps.texture;
                }

                cubeMapCaps = (DdsCubeMapCaps)r.ReadUInt32();
                if (cubeMapCaps != 0)
                {
                    Console.WriteLine(String.Format(
                        "Only simple DDS Textures are supported.  This DDS has cube map capabilities: {0}.  At 0x{1:X8}.  Clearing unsupported capabilities..."
                        , cubeMapCaps
                        , s.Position
                        ));
                    cubeMapCaps = 0;
                }

                unusedCaps3 = r.ReadUInt32();
                unusedCaps4 = r.ReadUInt32();
                reserved2 = r.ReadUInt32();

                unusedCaps3 = unusedCaps4 = reserved2 = 0;

                // -- DDS_HEADER_DX10 header10 -- Not Supported
            }
Beispiel #27
0
            uint reserved2;//124
            #endregion

            public DdsHeader(DdsFormat ddsFormat, int width, int height)
            {
                this.magic = DdsMagic.dds_;
                this.size = 124;
                //flags
                this.height = (uint)height;
                this.width = (uint)width;
                //pitchOrLinearSize
                this.depth = 0;
                this.numMipMaps = 0;
                for (int i = 0; i < reserved1.Length; i++) this.reserved1[i] = 0;
                this.pixelFormat = new DdsPixelFormat(ddsFormat);
                this.surfaceCaps = DdsSurfaceCaps.texture;
                this.cubeMapCaps = 0;
                this.unusedCaps3 = 0;
                this.unusedCaps4 = 0;
                this.reserved2 = 0;

                this.flags = writeFlags | (IsBlockCompressed ? DdsFlags.linearSize : DdsFlags.pitch);
                this.pitchOrLinearSize = IsBlockCompressed ? LinearSize : Pitch;
            }
Beispiel #28
0
 public DdsOptions(DdsPixelFormat pixelFormat, short width, short height, short mipMapCount)
     : this(pixelFormat, width, height, depth : 0, mipMapCount : mipMapCount)
 {
 }
Beispiel #29
0
    private static Format GetDXGIFormat(DdsPixelFormat ddpf)
    {
        if ((ddpf.flags & DDS_RGB) != 0)
        {
            // Note that sRGB formats are written using the "DX10" extended header

            switch (ddpf.RGBBitCount)
            {
            case 32:
                if (ddpf.IsBitMask(0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000))
                {
                    return(Format.R8G8B8A8_UNorm);
                }

                if (ddpf.IsBitMask(0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000))
                {
                    return(Format.B8G8R8A8_UNorm);
                }

                if (ddpf.IsBitMask(0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000))
                {
                    return(Format.B8G8R8X8_UNorm);
                }

                // No DXGI format maps to ddpf.ISBITMASK(0x000000ff,0x0000ff00,0x00ff0000,0x00000000) aka D3DFMT_X8B8G8R8

                // Note that many common DDS reader/writers (including D3DX) swap the
                // the RED/BLUE masks for 10:10:10:2 formats. We assume
                // below that the 'backwards' header mask is being used since it is most
                // likely written by D3DX. The more robust solution is to use the 'DX10'
                // header extension and specify the Format.R10G10B10A2_UNorm format directly

                // For 'correct' writers, this should be 0x000003ff,0x000ffc00,0x3ff00000 for RGB data
                if (ddpf.IsBitMask(0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000))
                {
                    return(Format.R10G10B10A2_UNorm);
                }

                // No DXGI format maps to ddpf.ISBITMASK(0x000003ff,0x000ffc00,0x3ff00000,0xc0000000) aka D3DFMT_A2R10G10B10

                if (ddpf.IsBitMask(0x0000ffff, 0xffff0000, 0x00000000, 0x00000000))
                {
                    return(Format.R16G16_UNorm);
                }

                if (ddpf.IsBitMask(0xffffffff, 0x00000000, 0x00000000, 0x00000000))
                {
                    // Only 32-bit color channel format in D3D9 was R32F
                    return(Format.R32_Float);                            // D3DX writes this out as a FourCC of 114
                }
                break;

            case 24:
                // No 24bpp DXGI formats aka D3DFMT_R8G8B8
                break;

            case 16:
                if (ddpf.IsBitMask(0x7c00, 0x03e0, 0x001f, 0x8000))
                {
                    return(Format.B5G5R5A1_UNorm);
                }
                if (ddpf.IsBitMask(0xf800, 0x07e0, 0x001f, 0x0000))
                {
                    return(Format.B5G6R5_UNorm);
                }

                // No DXGI format maps to ddpf.ISBITMASK(0x7c00,0x03e0,0x001f,0x0000) aka D3DFMT_X1R5G5B5

                if (ddpf.IsBitMask(0x0f00, 0x00f0, 0x000f, 0xf000))
                {
                    return(Format.B4G4R4A4_UNorm);
                }

                // No DXGI format maps to ddpf.ISBITMASK(0x0f00,0x00f0,0x000f,0x0000) aka D3DFMT_X4R4G4B4

                // No 3:3:2, 3:3:2:8, or paletted DXGI formats aka D3DFMT_A8R3G3B2, D3DFMT_R3G3B2, D3DFMT_P8, D3DFMT_A8P8, etc.
                break;
            }
        }
        else if ((ddpf.flags & DDS_LUMINANCE) != 0)
        {
            if (8 == ddpf.RGBBitCount)
            {
                if (ddpf.IsBitMask(0x000000ff, 0x00000000, 0x00000000, 0x00000000))
                {
                    return(Format.R8_UNorm);                    // D3DX10/11 writes this out as DX10 extension
                }

                // No DXGI format maps to ddpf.ISBITMASK(0x0f,0x00,0x00,0xf0) aka D3DFMT_A4L4

                if (ddpf.IsBitMask(0x000000ff, 0x00000000, 0x00000000, 0x0000ff00))
                {
                    return(Format.R8G8_UNorm);                    // Some DDS writers assume the bitcount should be 8 instead of 16
                }
            }

            if (16 == ddpf.RGBBitCount)
            {
                if (ddpf.IsBitMask(0x0000ffff, 0x00000000, 0x00000000, 0x00000000))
                {
                    return(Format.R16_UNorm);                    // D3DX10/11 writes this out as DX10 extension
                }
                if (ddpf.IsBitMask(0x000000ff, 0x00000000, 0x00000000, 0x0000ff00))
                {
                    return(Format.R8G8_UNorm);                    // D3DX10/11 writes this out as DX10 extension
                }
            }
        }
        else if ((ddpf.flags & DDS_ALPHA) != 0)
        {
            if (8 == ddpf.RGBBitCount)
            {
                return(Format.A8_UNorm);
            }
        }
        else if ((ddpf.flags & DDS_BUMPDUDV) != 0)
        {
            if (16 == ddpf.RGBBitCount)
            {
                if (ddpf.IsBitMask(0x00ff, 0xff00, 0x0000, 0x0000))
                {
                    return(Format.R8G8_SNorm);                    // D3DX10/11 writes this out as DX10 extension
                }
            }

            if (32 == ddpf.RGBBitCount)
            {
                if (ddpf.IsBitMask(0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000))
                {
                    return(Format.R8G8B8A8_SNorm);                    // D3DX10/11 writes this out as DX10 extension
                }
                if (ddpf.IsBitMask(0x0000ffff, 0xffff0000, 0x00000000, 0x00000000))
                {
                    return(Format.R16G16_SNorm);                    // D3DX10/11 writes this out as DX10 extension
                }

                // No DXGI format maps to ddpf.ISBITMASK(0x3ff00000, 0x000ffc00, 0x000003ff, 0xc0000000) aka D3DFMT_A2W10V10U10
            }
        }
        else if ((ddpf.flags & DDS_FOURCC) != 0)
        {
            if (MakeFourCC('D', 'X', 'T', '1') == ddpf.fourCC)
            {
                return(Format.BC1_UNorm);
            }
            if (MakeFourCC('D', 'X', 'T', '3') == ddpf.fourCC)
            {
                return(Format.BC2_UNorm);
            }
            if (MakeFourCC('D', 'X', 'T', '5') == ddpf.fourCC)
            {
                return(Format.BC3_UNorm);
            }

            // While pre-multiplied alpha isn't directly supported by the DXGI formats,
            // they are basically the same as these BC formats so they can be mapped
            if (MakeFourCC('D', 'X', 'T', '2') == ddpf.fourCC)
            {
                return(Format.BC2_UNorm);
            }
            if (MakeFourCC('D', 'X', 'T', '4') == ddpf.fourCC)
            {
                return(Format.BC3_UNorm);
            }

            if (MakeFourCC('A', 'T', 'I', '1') == ddpf.fourCC)
            {
                return(Format.BC4_UNorm);
            }
            if (MakeFourCC('B', 'C', '4', 'U') == ddpf.fourCC)
            {
                return(Format.BC4_UNorm);
            }
            if (MakeFourCC('B', 'C', '4', 'S') == ddpf.fourCC)
            {
                return(Format.BC4_SNorm);
            }

            if (MakeFourCC('A', 'T', 'I', '2') == ddpf.fourCC)
            {
                return(Format.BC5_UNorm);
            }
            if (MakeFourCC('B', 'C', '5', 'U') == ddpf.fourCC)
            {
                return(Format.BC5_UNorm);
            }
            if (MakeFourCC('B', 'C', '5', 'S') == ddpf.fourCC)
            {
                return(Format.BC5_SNorm);
            }

            // BC6H and BC7 are written using the "DX10" extended header

            if (MakeFourCC('R', 'G', 'B', 'G') == ddpf.fourCC)
            {
                return(Format.R8G8_B8G8_UNorm);
            }
            if (MakeFourCC('G', 'R', 'G', 'B') == ddpf.fourCC)
            {
                return(Format.G8R8_G8B8_UNorm);
            }

            if (MakeFourCC('Y', 'U', 'Y', '2') == ddpf.fourCC)
            {
                return(Format.YUY2);
            }

            // Check for D3DFORMAT enums being set here
            switch (ddpf.fourCC)
            {
            case 36:                     // D3DFMT_A16B16G16R16
                return(Format.R16G16B16A16_UNorm);

            case 110:                     // D3DFMT_Q16W16V16U16
                return(Format.R16G16B16A16_SNorm);

            case 111:                     // D3DFMT_R16F
                return(Format.R16_Float);

            case 112:                     // D3DFMT_G16R16F
                return(Format.R16G16_Float);

            case 113:                     // D3DFMT_A16B16G16R16F
                return(Format.R16G16B16A16_Float);

            case 114:                     // D3DFMT_R32F
                return(Format.R32_Float);

            case 115:                     // D3DFMT_G32R32F
                return(Format.R32G32_Float);

            case 116:                     // D3DFMT_A32B32G32R32F
                return(Format.R32G32B32A32_Float);
            }
        }

        return(Format.Unknown);
    }
 public DdsHeader()
 {
     m_pixelFormat	= new DdsPixelFormat();
 }
        public override async Task SetObject(string filename, List <DomainNameTableEntry> nameTable, object configuration)
        {
            DdsSaveConfig config = configuration as DdsSaveConfig ?? new DdsSaveConfig(FileFormat.Unknown, 0, 0, false, false);

            DdsFile image = await Task.Run(() => new DdsFile(filename));

            bool skipFirstMip = false;

            int width  = image.Width;
            int height = image.Height;

            if (MipMaps[0].ImageData == null || MipMaps[0].ImageData.Length == 0)
            {
                width  *= 2;
                height *= 2;

                skipFirstMip = true;
            }

            DomainPropertyIntValue sizeX = PropertyHeader.GetProperty("SizeX").FirstOrDefault()?.Value as DomainPropertyIntValue;
            DomainPropertyIntValue sizeY = PropertyHeader.GetProperty("SizeY").FirstOrDefault()?.Value as DomainPropertyIntValue;

            sizeX?.SetPropertyValue(skipFirstMip ? width * 2 : width);
            sizeY?.SetPropertyValue(skipFirstMip ? height * 2 : height);

            DomainPropertyIntValue mipTailBaseIdx = PropertyHeader.GetProperty("MipTailBaseIdx").FirstOrDefault()?.Value as DomainPropertyIntValue;

            int indexSize = width > height ? width : height;

            mipTailBaseIdx?.SetPropertyValue((int)Math.Log(skipFirstMip ? indexSize * 2 : indexSize, 2));

            DomainPropertyStringValue filePath = PropertyHeader.GetProperty("SourceFilePath").FirstOrDefault()?.Value as DomainPropertyStringValue;
            DomainPropertyStringValue fileTime = PropertyHeader.GetProperty("SourceFileTimestamp").FirstOrDefault()?.Value as DomainPropertyStringValue;

            filePath?.SetPropertyValue(filename);
            fileTime?.SetPropertyValue(File.GetLastWriteTime(filename).ToString("yyyy-MM-dd hh:mm:ss"));

            DomainPropertyByteValue pfFormat = PropertyHeader.GetProperty("Format").FirstOrDefault()?.Value as DomainPropertyByteValue;

            FileFormat imageFormat = FileFormat.Unknown;

            if (pfFormat != null)
            {
                imageFormat = DdsPixelFormat.ParseFileFormat(pfFormat.PropertyString);
            }

            if (imageFormat == FileFormat.Unknown)
            {
                throw new Exception($"Unknown DDS File Format ({pfFormat?.PropertyString ?? "Unknown"}).");
            }

            config.FileFormat = imageFormat;

            MipMaps.Clear();

            if (skipFirstMip)
            {
                MipMaps.Add(new DomainMipMap {
                    ImageData = null,
                    Width     = width,
                    Height    = height
                });
            }

            image.GenerateMipMaps(4, 4);

            foreach (DdsMipMap mipMap in image.MipMaps.OrderByDescending(mip => mip.Width))
            {
                MipMaps.Add(new DomainMipMap {
                    ImageData = image.WriteMipMap(mipMap, config),
                    Width     = mipMap.Width,
                    Height    = mipMap.Height
                });
            }
        }
Beispiel #32
0
 static SurfaceFormat GetSurfaceFormat(ref DdsPixelFormat pixelFormat, out bool rbSwap)
 {
     rbSwap = false;
     if (pixelFormat.dwFlags.HasFlag(Ddpf.FourCC))
     {
         // It is a compressed format
         switch (pixelFormat.dwFourCC)
         {
             case FourCC.Dxt1:
                 return SurfaceFormat.Dxt1;
             case FourCC.Dxt2:
                 throw new ContentLoadException("Unsupported compression format DXT2");
             case FourCC.Dxt3:
                 return SurfaceFormat.Dxt3;
             case FourCC.Dxt4:
                 throw new ContentLoadException("Unsupported compression format DXT4");
             case FourCC.Dxt5:
                 return SurfaceFormat.Dxt5;
         }
     }
     else if (pixelFormat.dwFlags.HasFlag(Ddpf.Rgb))
     {
         // Uncompressed format
         if (pixelFormat.dwFlags.HasFlag(Ddpf.AlphaPixels))
         {
             // Format contains RGB and A
             if (pixelFormat.dwRgbBitCount == 16)
             {
                 if (pixelFormat.dwABitMask == 0xF)
                 {
                     rbSwap = pixelFormat.dwBBitMask == 0xF0;
                     return SurfaceFormat.Bgra4444;
                 }
                 rbSwap = pixelFormat.dwBBitMask == 0x3E;
                 return SurfaceFormat.Bgra5551;
             }
             else if (pixelFormat.dwRgbBitCount == 32)
             {
                 rbSwap = pixelFormat.dwBBitMask == 0xFF00;
                 return SurfaceFormat.Color;
             }
             throw new ContentLoadException("Unsupported RGBA pixel format");
         }
         else
         {
             // Format contains RGB only
             if (pixelFormat.dwRgbBitCount == 16)
             {
                 rbSwap = pixelFormat.dwBBitMask == 0x1F;
                 return SurfaceFormat.Bgr565;
             }
             throw new ContentLoadException("Unsupported RGB pixel format");
         }
     }
     throw new ContentLoadException("Unsupported pixel format");
 }
Beispiel #33
0
 public DdsHeader()
 {
     m_pixelFormat = new DdsPixelFormat();
 }