public DdsHeader(
     uint size,
     DdsFlags flags,
     uint height,
     uint width,
     uint pitchOrLinearSize,
     uint depth,
     uint mipMapCount,
     uint[] reserved1,
     DdsPixelFormat pixelFormat,
     DdsCaps1 caps1,
     DdsCaps2 caps2,
     uint caps3,
     uint caps4,
     uint reserved2)
 {
     this.Size              = size;
     this.Flags             = flags;
     this.Height            = height;
     this.Width             = width;
     this.PitchOrLinearSize = pitchOrLinearSize;
     this.Depth             = depth;
     this.MipMapCount       = mipMapCount;
     this.Reserved1         = reserved1;
     this.PixelFormat       = pixelFormat;
     this.Caps1             = caps1;
     this.Caps2             = caps2;
     this.Caps3             = caps3;
     this.Caps4             = caps4;
     this.Reserved2         = reserved2;
 }
Beispiel #2
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 #3
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 #4
0
        private static void EncodeDDSHeader(BinaryWriter writer, TextureDescription description, DdsFlags flags)
        {
            if (!TextureHelper.IsValidDds(description.Format))
            throw new ArgumentException("Invalid texture format.", "description");

              if (TextureHelper.IsPalettized(description.Format))
            throw new NotSupportedException("Palettized texture formats are not supported.");

              if (description.ArraySize > 1)
              {
            if (description.ArraySize != 6 || description.Dimension != TextureDimension.Texture2D || description.Dimension != TextureDimension.TextureCube)
            {
              // Texture1D arrays, Texture2D arrays, and TextureCube arrays must be stored using 'DX10' extended header
              flags |= DdsFlags.ForceDX10Ext;
            }
              }

              if ((flags & DdsFlags.ForceDX10ExtMisc2) != 0)
            flags |= DdsFlags.ForceDX10Ext;

              PixelFormat ddpf = default(PixelFormat);
              if ((flags & DdsFlags.ForceDX10Ext) == 0)
              {
            switch (description.Format)
            {
              case DataFormat.R8G8B8A8_UNORM:
            ddpf = PixelFormat.A8B8G8R8;
            break;
              case DataFormat.R16G16_UNORM:
            ddpf = PixelFormat.G16R16;
            break;
              case DataFormat.R8G8_UNORM:
            ddpf = PixelFormat.A8L8;
            break;
              case DataFormat.R16_UNORM:
            ddpf = PixelFormat.L16;
            break;
              case DataFormat.R8_UNORM:
            ddpf = PixelFormat.L8;
            break;
              case DataFormat.A8_UNORM:
            ddpf = PixelFormat.A8;
            break;
              case DataFormat.R8G8_B8G8_UNORM:
            ddpf = PixelFormat.R8G8_B8G8;
            break;
              case DataFormat.G8R8_G8B8_UNORM:
            ddpf = PixelFormat.G8R8_G8B8;
            break;
              case DataFormat.BC1_UNORM:
            ddpf = PixelFormat.DXT1;
            break;
              case DataFormat.BC2_UNORM:
            ddpf = /* (description.AlphaMode == AlphaMode.Premultiplied) ? PixelFormat.DXT2 : */ PixelFormat.DXT3;
            break;
              case DataFormat.BC3_UNORM:
            ddpf = /* (description.AlphaMode == AlphaMode.Premultiplied) ? PixelFormat.DXT2 : */ PixelFormat.DXT5;
            break;
              case DataFormat.BC4_UNORM:
            ddpf = PixelFormat.BC4_UNorm;
            break;
              case DataFormat.BC4_SNORM:
            ddpf = PixelFormat.BC4_SNorm;
            break;
              case DataFormat.BC5_UNORM:
            ddpf = PixelFormat.BC5_UNorm;
            break;
              case DataFormat.BC5_SNORM:
            ddpf = PixelFormat.BC5_SNorm;
            break;
              case DataFormat.B5G6R5_UNORM:
            ddpf = PixelFormat.R5G6B5;
            break;
              case DataFormat.B5G5R5A1_UNORM:
            ddpf = PixelFormat.A1R5G5B5;
            break;
              case DataFormat.R8G8_SNORM:
            ddpf = PixelFormat.V8U8;
            break;
              case DataFormat.R8G8B8A8_SNORM:
            ddpf = PixelFormat.Q8W8V8U8;
            break;
              case DataFormat.R16G16_SNORM:
            ddpf = PixelFormat.V16U16;
            break;
              case DataFormat.B8G8R8A8_UNORM:
            ddpf = PixelFormat.A8R8G8B8;
            break; // DXGI 1.1
              case DataFormat.B8G8R8X8_UNORM:
            ddpf = PixelFormat.X8R8G8B8;
            break; // DXGI 1.1
              //#if DIRECTX11_1
              case DataFormat.B4G4R4A4_UNORM:
            ddpf = PixelFormat.A4R4G4B4;
            break;
              case DataFormat.YUY2:
            ddpf = PixelFormat.YUY2;
            break;
              //#endif
              // Legacy D3DX formats using D3DFMT enum value as FourCC
              case DataFormat.R32G32B32A32_FLOAT:
            ddpf.Size = Marshal.SizeOf(typeof(PixelFormat));
            ddpf.Flags = PixelFormatFlags.FourCC;
            ddpf.FourCC = 116; // D3DFMT_A32B32G32R32F
            break;
              case DataFormat.R16G16B16A16_FLOAT:
            ddpf.Size = Marshal.SizeOf(typeof(PixelFormat));
            ddpf.Flags = PixelFormatFlags.FourCC;
            ddpf.FourCC = 113; // D3DFMT_A16B16G16R16F
            break;
              case DataFormat.R16G16B16A16_UNORM:
            ddpf.Size = Marshal.SizeOf(typeof(PixelFormat));
            ddpf.Flags = PixelFormatFlags.FourCC;
            ddpf.FourCC = 36; // D3DFMT_A16B16G16R16
            break;
              case DataFormat.R16G16B16A16_SNORM:
            ddpf.Size = Marshal.SizeOf(typeof(PixelFormat));
            ddpf.Flags = PixelFormatFlags.FourCC;
            ddpf.FourCC = 110; // D3DFMT_Q16W16V16U16
            break;
              case DataFormat.R32G32_FLOAT:
            ddpf.Size = Marshal.SizeOf(typeof(PixelFormat));
            ddpf.Flags = PixelFormatFlags.FourCC;
            ddpf.FourCC = 115; // D3DFMT_G32R32F
            break;
              case DataFormat.R16G16_FLOAT:
            ddpf.Size = Marshal.SizeOf(typeof(PixelFormat));
            ddpf.Flags = PixelFormatFlags.FourCC;
            ddpf.FourCC = 112; // D3DFMT_G16R16F
            break;
              case DataFormat.R32_FLOAT:
            ddpf.Size = Marshal.SizeOf(typeof(PixelFormat));
            ddpf.Flags = PixelFormatFlags.FourCC;
            ddpf.FourCC = 114; // D3DFMT_R32F
            break;
              case DataFormat.R16_FLOAT:
            ddpf.Size = Marshal.SizeOf(typeof(PixelFormat));
            ddpf.Flags = PixelFormatFlags.FourCC;
            ddpf.FourCC = 111; // D3DFMT_R16F
            break;
            }
              }

              writer.Write(MagicHeader);

              var header = new Header();
              header.Size = Marshal.SizeOf(typeof(Header));
              header.Flags = HeaderFlags.Texture;
              header.SurfaceFlags = SurfaceFlags.Texture;

              if (description.MipLevels > 0)
              {
            header.Flags |= HeaderFlags.Mipmap;
            header.MipMapCount = description.MipLevels;

            if (header.MipMapCount > 1)
              header.SurfaceFlags |= SurfaceFlags.Mipmap;
              }

              switch (description.Dimension)
              {
            case TextureDimension.Texture1D:
              header.Height = description.Height;
              header.Width = header.Depth = 1;
              break;

            case TextureDimension.Texture2D:
            case TextureDimension.TextureCube:
              header.Height = description.Height;
              header.Width = description.Width;
              header.Depth = 1;

              if (description.Dimension == TextureDimension.TextureCube)
              {
            header.SurfaceFlags |= SurfaceFlags.Cubemap;
            header.CubemapFlags |= CubemapFlags.AllFaces;
              }
              break;

            case TextureDimension.Texture3D:
              header.Flags |= HeaderFlags.Volume;
              header.CubemapFlags |= CubemapFlags.Volume;
              header.Height = description.Height;
              header.Width = description.Width;
              header.Depth = description.Depth;
              break;

            default:
              throw new NotSupportedException("The specified texture dimension is not supported.");
              }

              int rowPitch, slicePitch;
              TextureHelper.ComputePitch(description.Format, description.Width, description.Height, out rowPitch, out slicePitch);

              if (TextureHelper.IsBCn(description.Format))
              {
            header.Flags |= HeaderFlags.LinearSize;
            header.PitchOrLinearSize = slicePitch;
              }
              else
              {
            header.Flags |= HeaderFlags.Pitch;
            header.PitchOrLinearSize = rowPitch;
              }

              if (ddpf.Size != 0)
              {
            header.PixelFormat = ddpf;
            writer.BaseStream.WriteStruct(header);
              }
              else
              {
            header.PixelFormat = PixelFormat.DX10;

            var ext = new HeaderDXT10();
            ext.DXGIFormat = description.Format;
            switch (description.Dimension)
            {
              case TextureDimension.Texture1D:
            ext.ResourceDimension = ResourceDimension.Texture1D;
            break;
              case TextureDimension.Texture2D:
              case TextureDimension.TextureCube:
            ext.ResourceDimension = ResourceDimension.Texture2D;
            break;
              case TextureDimension.Texture3D:
            ext.ResourceDimension = ResourceDimension.Texture3D;
            break;
            }

            if (description.Dimension == TextureDimension.TextureCube)
            {
              ext.MiscFlags |= ResourceOptionFlags.TextureCube;
              ext.ArraySize = description.ArraySize / 6;
            }
            else
            {
              ext.ArraySize = description.ArraySize;
            }

            if ((flags & DdsFlags.ForceDX10ExtMisc2) != 0)
            {
              // This was formerly 'reserved'. D3DX10 and D3DX11 will fail if this value is anything other than 0.
              //ext.MiscFlags2 = description.MiscFlags2;
              throw new NotImplementedException("DdsFlags.ForceDX10ExtMisc2 is not implemented.");
            }

            writer.BaseStream.WriteStruct(header);
            writer.BaseStream.WriteStruct(ext);
              }
        }
Beispiel #5
0
        private static TextureDescription DecodeDDSHeader(BinaryReader reader, DdsFlags flags, out ConversionFlags convFlags)
        {
            Debug.Assert(Marshal.SizeOf(typeof(Header)) == 124, "DDS Header size mismatch");
              Debug.Assert(Marshal.SizeOf(typeof(HeaderDXT10)) == 20, "DDS DX10 Extended Header size mismatch");

              var description = new TextureDescription();
              convFlags = ConversionFlags.None;

              long size = reader.BaseStream.Length - reader.BaseStream.Position;
              int sizeOfTGAHeader = Marshal.SizeOf(typeof(Header));
              if (size < sizeOfTGAHeader)
            throw new InvalidDataException("The DDS file is corrupt.");

              // DDS files always start with the same magic number ("DDS ").
              if (reader.ReadUInt32() != MagicHeader)
            throw new InvalidDataException("The file does not appear to be a DDS file.");

              var header = reader.BaseStream.ReadStruct<Header>();

              // Verify header to validate DDS file
              if (header.Size != Marshal.SizeOf(typeof(Header))
              || header.PixelFormat.Size != Marshal.SizeOf(typeof(PixelFormat)))
            throw new InvalidDataException("Incorrect sizes in DDS file.");

              description.MipLevels = header.MipMapCount;
              if (description.MipLevels == 0)
            description.MipLevels = 1;

              // Check for DX10 extension
              if ((header.PixelFormat.Flags & PixelFormatFlags.FourCC) != 0
              && (new FourCC('D', 'X', '1', '0') == header.PixelFormat.FourCC))
              {
            // Buffer must be big enough for both headers and magic value
            if (reader.BaseStream.Length < (Marshal.SizeOf(typeof(Header)) + Marshal.SizeOf(typeof(HeaderDXT10)) + sizeof(uint)))
              throw new InvalidDataException("The DDS files is truncated.");

            var headerDX10 = reader.BaseStream.ReadStruct<HeaderDXT10>();
            convFlags |= ConversionFlags.DX10;

            description.ArraySize = headerDX10.ArraySize;
            if (description.ArraySize == 0)
              throw new InvalidDataException("Invalid array size specified in DDS file.");

            description.Format = headerDX10.DXGIFormat;
            if (!TextureHelper.IsValidDds(description.Format) || TextureHelper.IsPalettized(description.Format))
              throw new InvalidDataException("Invalid format specified in DDS file.");

            switch (headerDX10.ResourceDimension)
            {
              case ResourceDimension.Texture1D:

            // D3DX writes 1D textures with a fixed Height of 1
            if ((header.Flags & HeaderFlags.Height) != 0 && header.Height != 1)
              throw new InvalidDataException("Invalid height for 1D texture specified in DDS file.");

            description.Dimension = TextureDimension.Texture1D;
            description.Width = header.Width;
            description.Height = 1;
            description.Depth = 1;
            break;

              case ResourceDimension.Texture2D:
            if ((headerDX10.MiscFlags & ResourceOptionFlags.TextureCube) != 0)
            {
              description.Dimension = TextureDimension.TextureCube;
              description.ArraySize *= 6;
            }
            else
            {
              description.Dimension = TextureDimension.Texture2D;
            }

            description.Width = header.Width;
            description.Height = header.Height;
            description.Depth = 1;
            break;

              case ResourceDimension.Texture3D:
            if ((header.Flags & HeaderFlags.Volume) == 0)
              throw new InvalidDataException("Volume flag for 3D texture is missing in DDS file.");

            if (description.ArraySize > 1)
              throw new InvalidDataException("Invalid array size for 3D texture specified in DDS file.");

            description.Dimension = TextureDimension.Texture3D;
            description.Width = header.Width;
            description.Height = header.Height;
            description.Depth = header.Depth;
            break;

              default:
            throw new InvalidDataException(string.Format(CultureInfo.InvariantCulture, "Invalid texture dimension specified in DDS file."));
            }
              }
              else
              {
            description.ArraySize = 1;

            if ((header.Flags & HeaderFlags.Volume) != 0)
            {
              description.Dimension = TextureDimension.Texture3D;
              description.Width = header.Width;
              description.Height = header.Height;
              description.Depth = header.Depth;
            }
            else
            {
              if ((header.CubemapFlags & CubemapFlags.CubeMap) != 0)
              {
            // We require all six faces to be defined
            if ((header.CubemapFlags & CubemapFlags.AllFaces) != CubemapFlags.AllFaces)
              throw new InvalidDataException("Cube map faces missing in DDS file. All six faces required.");

            description.Dimension = TextureDimension.TextureCube;
            description.ArraySize = 6;
              }
              else
              {
            description.Dimension = TextureDimension.Texture2D;
              }

              description.Width = header.Width;
              description.Height = header.Height;
              description.Depth = 1;

              // Note there's no way for a legacy Direct3D 9 DDS to express a '1D' texture
            }

            description.Format = GetDXGIFormat(ref header.PixelFormat, flags, out convFlags);

            if (description.Format == DataFormat.Unknown)
              throw new NotSupportedException("The texture format used in the DDS file is not supported.");

            // Premultiplied formats are considered deprecated.
            //if ((convFlags & ConversionFlags.PremultipliedAlpha) != 0)
            //  Description.AlphaMode = AlphaMode.Premultiplied;

            // Special flag for handling LUMINANCE legacy formats
            if ((flags & DdsFlags.ExpandLuminance) != 0)
            {
              switch (description.Format)
              {
            case DataFormat.R8_UNORM:
              description.Format = DataFormat.R8G8B8A8_UNORM;
              convFlags |= ConversionFlags.FormatL8 | ConversionFlags.Expand;
              break;

            case DataFormat.R8G8_UNORM:
              description.Format = DataFormat.R8G8B8A8_UNORM;
              convFlags |= ConversionFlags.FormatA8L8 | ConversionFlags.Expand;
              break;

            case DataFormat.R16_UNORM:
              description.Format = DataFormat.R16G16B16A16_UNORM;
              convFlags |= ConversionFlags.FormatL16 | ConversionFlags.Expand;
              break;
              }
            }
              }

              // Special flag for handling BGR DXGI 1.1 formats
              if ((flags & DdsFlags.ForceRgb) != 0)
              {
            switch (description.Format)
            {
              case DataFormat.B8G8R8A8_UNORM:
            description.Format = DataFormat.R8G8B8A8_UNORM;
            convFlags |= ConversionFlags.Swizzle;
            break;

              case DataFormat.B8G8R8X8_UNORM:
            description.Format = DataFormat.R8G8B8A8_UNORM;
            convFlags |= ConversionFlags.Swizzle | ConversionFlags.NoAlpha;
            break;

              case DataFormat.B8G8R8A8_TYPELESS:
            description.Format = DataFormat.R8G8B8A8_TYPELESS;
            convFlags |= ConversionFlags.Swizzle;
            break;

              case DataFormat.B8G8R8A8_UNORM_SRGB:
            description.Format = DataFormat.R8G8B8A8_UNORM_SRGB;
            convFlags |= ConversionFlags.Swizzle;
            break;

              case DataFormat.B8G8R8X8_TYPELESS:
            description.Format = DataFormat.R8G8B8A8_TYPELESS;
            convFlags |= ConversionFlags.Swizzle | ConversionFlags.NoAlpha;
            break;

              case DataFormat.B8G8R8X8_UNORM_SRGB:
            description.Format = DataFormat.R8G8B8A8_UNORM_SRGB;
            convFlags |= ConversionFlags.Swizzle | ConversionFlags.NoAlpha;
            break;
            }
              }

              // Special flag for handling 16bpp formats
              if ((flags & DdsFlags.No16Bpp) != 0)
              {
            switch (description.Format)
            {
              case DataFormat.B5G6R5_UNORM:
              case DataFormat.B5G5R5A1_UNORM:
              case DataFormat.B4G4R4A4_UNORM:
            description.Format = DataFormat.R8G8B8A8_UNORM;
            convFlags |= ConversionFlags.Expand;
            if (description.Format == DataFormat.B5G6R5_UNORM)
              convFlags |= ConversionFlags.NoAlpha;
            break;
            }
              }
              return description;
        }
Beispiel #6
0
        /// <summary>
        /// Saves the specified texture in DDS format.
        /// </summary>
        /// <param name="texture">The texture.</param>
        /// <param name="stream">The stream to write to.</param>
        /// <param name="flags">Additional options.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="texture"/> or <paramref name="stream"/> is <see langword="null"/>.
        /// </exception>
        public static void Save(Texture texture, Stream stream, DdsFlags flags)
        {
            if (texture == null)
            throw new ArgumentNullException("texture");
              if (stream == null)
            throw new ArgumentNullException("stream");

            #if NET45
              using (var writer = new BinaryWriter(stream, Encoding.Default, true))
            #else
              using (var writer = new BinaryWriter(stream, Encoding.Default))   // Warning: Closes the stream!
            #endif
              {
            var description = texture.Description;
            EncodeDDSHeader(writer, description, flags);

            switch (description.Dimension)
            {
              case TextureDimension.Texture1D:
              case TextureDimension.Texture2D:
              case TextureDimension.TextureCube:
            {
              int index = 0;
              for (int item = 0; item < description.ArraySize; ++item)
              {
                for (int level = 0; level < description.MipLevels; ++level)
                {
                  var image = texture.Images[index];
                  stream.Write(image.Data, 0, image.Data.Length);
                  ++index;
                }
              }
            }
            break;

              case TextureDimension.Texture3D:
            {
              if (description.ArraySize != 1)
                throw new NotSupportedException("Arrays of volume textures are not supported.");

              int d = description.Depth;

              int index = 0;
              for (int level = 0; level < description.MipLevels; ++level)
              {
                for (int slice = 0; slice < d; ++slice)
                {
                  var image = texture.Images[index];
                  stream.Write(image.Data, 0, image.Data.Length);
                  ++index;
                }

                if (d > 1)
                  d >>= 1;
              }
            }
            break;

              default:
            throw new NotSupportedException("The specified texture dimension is not supported.");
            }
              }
        }
Beispiel #7
0
        /// <summary>
        /// Loads the specified DDS texture.
        /// </summary>
        /// <param name="stream">The stream to read from.</param>
        /// <param name="flags">Additional options.</param>
        /// <returns>The <see cref="Texture"/>.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="stream"/> is <see langword="null"/>.
        /// </exception>
        public static Texture Load(Stream stream, DdsFlags flags)
        {
            if (stream == null)
            throw new ArgumentNullException("stream");

              using (var reader = new BinaryReader(stream))
              {
            ConversionFlags conversionFlags;
            var description = DecodeDDSHeader(reader, flags, out conversionFlags);

            uint[] pal8 = null;
            if ((conversionFlags & ConversionFlags.Pal8) != 0)
            {
              pal8 = new uint[256];
              for (int i = 0; i < pal8.Length; i++)
            pal8[i] = reader.ReadUInt32();
            }

            var computePitchFlags = (flags & DdsFlags.LegacyDword) != 0 ? ComputePitchFlags.LegacyDword : ComputePitchFlags.None;
            return CopyImage(reader, description, computePitchFlags, conversionFlags, pal8);
              }
        }
Beispiel #8
0
        // 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 DXGI_FORMAT_R10G10B10A2_UNORM format directly
        // We do not support the following legacy Direct3D 9 formats:
        //      D3DFMT_A2W10V10U10
        //      BumpLuminance D3DFMT_L6V5U5, D3DFMT_X8L8V8U8
        //      FourCC 117 D3DFMT_CxV8U8
        //      ZBuffer D3DFMT_D16_LOCKABLE
        //      FourCC 82 D3DFMT_D32F_LOCKABLE
        private static DataFormat GetDXGIFormat(ref PixelFormat pixelFormat, DdsFlags flags, out ConversionFlags conversionFlags)
        {
            conversionFlags = ConversionFlags.None;

              int index;
              for (index = 0; index < LegacyMaps.Length; ++index)
              {
            var entry = LegacyMaps[index];

            if ((pixelFormat.Flags & entry.PixelFormat.Flags) != 0)
            {
              if ((entry.PixelFormat.Flags & PixelFormatFlags.FourCC) != 0)
              {
            if (pixelFormat.FourCC == entry.PixelFormat.FourCC)
              break;
              }
              else if ((entry.PixelFormat.Flags & PixelFormatFlags.Pal8) != 0)
              {
            if (pixelFormat.RGBBitCount == entry.PixelFormat.RGBBitCount)
              break;
              }
              else if (pixelFormat.RGBBitCount == entry.PixelFormat.RGBBitCount)
              {
            // RGB, RGBA, ALPHA, LUMINANCE
            if (pixelFormat.RBitMask == entry.PixelFormat.RBitMask
                && pixelFormat.GBitMask == entry.PixelFormat.GBitMask
                && pixelFormat.BBitMask == entry.PixelFormat.BBitMask
                && pixelFormat.ABitMask == entry.PixelFormat.ABitMask)
              break;
              }
            }
              }

              if (index >= LegacyMaps.Length)
            return DataFormat.Unknown;

              conversionFlags = LegacyMaps[index].ConversionFlags;
              var format = LegacyMaps[index].Format;

              if ((conversionFlags & ConversionFlags.Expand) != 0 && (flags & DdsFlags.NoLegacyExpansion) != 0)
            return DataFormat.Unknown;

              if (format == DataFormat.R10G10B10A2_UNORM && (flags & DdsFlags.NoR10B10G10A2Fixup) != 0)
              {
            conversionFlags ^= ConversionFlags.Swizzle;
              }

              return format;
        }