Exemplo n.º 1
0
        /// <summary>
        /// Reads a DDS header from a stream. On return, the stream will be positioned at the beginning of the texture data.
        /// </summary>
        /// <param name="stream">The stream to read from.</param>
        /// <returns>The header that was read.</returns>
        /// <exception cref="System.InvalidOperationException">Thrown if the DDS header is invalid.</exception>
        public static DdsHeader Read(Stream stream)
        {
            var reader = new BinaryReader(stream);

            if (stream.Length - stream.Position < 128)
            {
                throw new InvalidOperationException("Invalid DDS file: header is too small");
            }
            var result = new DdsHeader();

            // Read and verify magic
            if (reader.ReadUInt32() != DdsFourCc.FromString("DDS "))
            {
                throw new InvalidOperationException("Invalid DDS file: invalid header magic");
            }

            // Read the DDS header
            result.ReadDdsHeader(reader);

            // If the format FourCC is 'DX10', read the extended header
            if (result.FourCc == DdsFourCc.FromString("DX10"))
            {
                result.ReadDdsD3D10Header(reader);
            }

            return(result);
        }
Exemplo n.º 2
0
 private void WriteDdsPixelFormat(BinaryWriter writer)
 {
     writer.Write(32);
     writer.Write((uint)CalculateFormatFlags());
     writer.Write((D3D10Format == DxgiFormat.Unknown) ? FourCc : DdsFourCc.FromString("DX10"));
     writer.Write(BitsPerPixel);
     writer.Write(RBitMask);
     writer.Write(GBitMask);
     writer.Write(BBitMask);
     writer.Write(ABitMask);
 }
Exemplo n.º 3
0
        /// <summary>
        /// Writes the DDS header to a stream. On return, the stream will be positioned where the texture data should go.
        /// </summary>
        /// <param name="stream">The stream to write to.</param>
        /// <exception cref="System.InvalidOperationException">Thrown if an error occurs while saving.</exception>
        public void WriteTo(Stream stream)
        {
            var writer = new BinaryWriter(stream);

            writer.Write(DdsFourCc.FromString("DDS "));
            WriteDdsHeader(writer);
            if (D3D10Format != DxgiFormat.Unknown)
            {
                WriteDdsD3D10Header(writer);
            }
        }
Exemplo n.º 4
0
        public void InjectDds(TagSerializer serializer, TagDeserializer deserializer, Bitmap bitmap, int imageIndex, Stream ddsStream)
        {
            var resource    = bitmap.Resources[imageIndex].Resource;
            var newResource = (resource == null);
            ResourceSerializationContext    resourceContext;
            BitmapTextureResourceDefinition definition;

            if (newResource)
            {
                // Create a new resource reference
                resource = new ResourceReference
                {
                    DefinitionFixups = new List <ResourceDefinitionFixup>(),
                    D3DObjectFixups  = new List <D3DObjectFixup>(),
                    Type             = 1, // TODO: Map out this type enum instead of using numbers
                    Unknown68        = 1
                };
                bitmap.Resources[imageIndex].Resource = resource;
                resourceContext = new ResourceSerializationContext(resource);
                definition      = new BitmapTextureResourceDefinition
                {
                    Texture = new D3DPointer <BitmapTextureResourceDefinition.BitmapDefinition>
                    {
                        Definition = new BitmapTextureResourceDefinition.BitmapDefinition()
                    }
                };
            }
            else
            {
                // Deserialize the old definition
                resourceContext = new ResourceSerializationContext(resource);
                definition      = deserializer.Deserialize <BitmapTextureResourceDefinition>(resourceContext);
            }
            if (definition.Texture == null || definition.Texture.Definition == null)
            {
                throw new ArgumentException("Invalid bitmap definition");
            }
            var texture   = definition.Texture.Definition;
            var imageData = bitmap.Images[imageIndex];

            // Read the DDS header and modify the definition to match
            var dds      = DdsHeader.Read(ddsStream);
            var dataSize = (int)(ddsStream.Length - ddsStream.Position);

            texture.Data            = new ResourceDataReference(dataSize, new ResourceAddress(ResourceAddressType.Resource, 0));
            texture.Width           = (short)dds.Width;
            texture.Height          = (short)dds.Height;
            texture.Depth           = (sbyte)Math.Max(1, dds.Depth);
            texture.Levels          = (sbyte)Math.Max(1, dds.MipMapCount);
            texture.Type            = BitmapDdsFormatDetection.DetectType(dds);
            texture.D3DFormatUnused = (int)((dds.D3D10Format != DxgiFormat.Bc5UNorm) ? dds.FourCc : DdsFourCc.FromString("ATI2"));
            texture.Format          = BitmapDdsFormatDetection.DetectFormat(dds);

            // Set flags based on the format
            switch (texture.Format)
            {
            case BitmapFormat.Dxt1:
            case BitmapFormat.Dxt3:
            case BitmapFormat.Dxt5:
            case BitmapFormat.Dxn:
                texture.Flags = BitmapFlags.Compressed;
                break;

            default:
                texture.Flags = BitmapFlags.None;
                break;
            }
            if ((texture.Width & (texture.Width - 1)) == 0 && (texture.Height & (texture.Height - 1)) == 0)
            {
                texture.Flags |= BitmapFlags.PowerOfTwoDimensions;
            }

            // If creating a new image, then add a new resource, otherwise replace the existing one
            if (newResource)
            {
                _resourceManager.Add(resource, ResourceLocation.Textures, ddsStream);
            }
            else
            {
                _resourceManager.Replace(resource, ddsStream);
            }

            // Serialize the new resource definition
            serializer.Serialize(resourceContext, definition);

            // Modify the image data in the bitmap tag to match the definition
            imageData.Width       = texture.Width;
            imageData.Height      = texture.Height;
            imageData.Depth       = texture.Depth;
            imageData.Type        = texture.Type;
            imageData.Format      = texture.Format;
            imageData.Flags       = texture.Flags;
            imageData.MipmapCount = (sbyte)(texture.Levels - 1);
            imageData.DataOffset  = texture.Data.Address.Offset;
            imageData.DataSize    = texture.Data.Size;
            imageData.Unknown15   = texture.Unknown35;
        }
Exemplo n.º 5
0
        public void InjectDds(TagSerializer serializer, TagDeserializer deserializer, Bitmap bitmap, int imageIndex, Stream ddsStream, ResourceLocation location = ResourceLocation.Textures)
        {
            var resource    = bitmap.Resources[imageIndex].Resource;
            var newResource = (resource == null);
            ResourceSerializationContext resourceContext;
            BitmapTextureInteropResource definition;

            if (newResource)
            {
                // Create a new resource reference
                resource = new PageableResource
                {
                    Page     = new RawPage(),
                    Resource = new TagResourceGen3
                    {
                        ResourceFixups           = new List <TagResourceGen3.ResourceFixup>(),
                        ResourceDefinitionFixups = new List <TagResourceGen3.ResourceDefinitionFixup>(),
                        ResourceType             = TagResourceTypeGen3.Bitmap,
                        Unknown2 = 1
                    }
                };

                bitmap.Resources[imageIndex].Resource = resource;
                resourceContext = new ResourceSerializationContext(CacheContext, resource);
                definition      = new BitmapTextureInteropResource
                {
                    Texture = new TagStructureReference <BitmapTextureInteropResource.BitmapDefinition>
                    {
                        Definition = new BitmapTextureInteropResource.BitmapDefinition
                        {
                            Data        = new TagData(),
                            UnknownData = new TagData(),
                        }
                    }
                };
            }
            else
            {
                // Deserialize the old definition
                resourceContext = new ResourceSerializationContext(CacheContext, resource);
                definition      = deserializer.Deserialize <BitmapTextureInteropResource>(resourceContext);
            }
            if (definition.Texture == null || definition.Texture.Definition == null)
            {
                throw new ArgumentException("Invalid bitmap definition");
            }
            var texture   = definition.Texture.Definition;
            var imageData = bitmap.Images[imageIndex];

            // Read the DDS header and modify the definition to match
            var dds      = DdsHeader.Read(ddsStream);
            var dataSize = (int)(ddsStream.Length - ddsStream.Position);

            texture.Data        = new TagData(dataSize, new CacheResourceAddress(CacheResourceAddressType.Resource, 0));
            texture.Width       = (short)dds.Width;
            texture.Height      = (short)dds.Height;
            texture.Depth       = (sbyte)Math.Max(1, dds.Depth);
            texture.MipmapCount = (sbyte)Math.Max(1, dds.MipMapCount);
            texture.Type        = BitmapDdsFormatDetection.DetectType(dds);
            texture.D3DFormat   = (int)((dds.D3D10Format != DxgiFormat.Bc5UNorm) ? dds.FourCc : DdsFourCc.FromString("ATI2"));
            texture.Format      = BitmapDdsFormatDetection.DetectFormat(dds);

            // Set flags based on the format
            switch (texture.Format)
            {
            case BitmapFormat.Dxt1:
            case BitmapFormat.Dxt3:
            case BitmapFormat.Dxt5:
            case BitmapFormat.Dxn:
                texture.Flags = BitmapFlags.Compressed;
                break;

            default:
                texture.Flags = BitmapFlags.None;
                break;
            }
            if ((texture.Width & (texture.Width - 1)) == 0 && (texture.Height & (texture.Height - 1)) == 0)
            {
                texture.Flags |= BitmapFlags.PowerOfTwoDimensions;
            }

            // If creating a new image, then add a new resource, otherwise replace the existing one
            if (newResource)
            {
                resource.ChangeLocation(location);
                CacheContext.AddResource(resource, ddsStream);
            }
            else
            {
                CacheContext.ReplaceResource(resource, ddsStream);
            }

            // Serialize the new resource definition
            serializer.Serialize(resourceContext, definition);

            // Modify the image data in the bitmap tag to match the definition
            imageData.Width       = texture.Width;
            imageData.Height      = texture.Height;
            imageData.Depth       = texture.Depth;
            imageData.Type        = texture.Type;
            imageData.Format      = texture.Format;
            imageData.Flags       = texture.Flags;
            imageData.MipmapCount = (sbyte)(texture.MipmapCount - 1);
            imageData.DataOffset  = texture.Data.Address.Offset;
            imageData.DataSize    = texture.Data.Size;
            imageData.Curve       = (BitmapImageCurve)texture.Curve;
        }