public static CommandContext Create(CommandContext parent, OpenTagCache info, TagInstance tag, Bitmap bitmap) { var groupName = info.StringIds.GetString(tag.Group.Name); var context = new CommandContext(parent, string.Format("{0:X8}.{1}", tag.Index, groupName)); Populate(context, info, tag, bitmap); return context; }
public void InjectDds(Bitmap bitmap, int imageIndex, Stream ddsStream) { // Deserialize the old definition var resourceContext = new ResourceSerializationContext(bitmap.Resources[imageIndex].Resource); var definition = TagDeserializer.Deserialize<BitmapTextureResourceDefinition>(resourceContext); if (definition.Texture == null || definition.Texture.Definition == null) throw new ArgumentException("Invalid bitmap definition"); var texture = definition.Texture.Definition; // 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 (definition.Texture.Definition.Format) { case BitmapFormat.Dxt1: case BitmapFormat.Dxt3: case BitmapFormat.Dxt5: case BitmapFormat.Dxn: definition.Texture.Definition.Flags = BitmapFlags.Compressed; break; default: definition.Texture.Definition.Flags = BitmapFlags.None; break; } // Inject the resource data _resourceManager.Replace(bitmap.Resources[imageIndex].Resource, ddsStream); // Serialize the new resource definition TagSerializer.Serialize(resourceContext, definition); // Modify the image data in the bitmap tag to match the definition var imageData = bitmap.Images[imageIndex]; 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; }
public BitmImportCommand(OpenTagCache info, HaloTag tag, Bitmap bitmap) : base(CommandFlags.None, "import", "Import an image from a DDS file", "import <image index> <path>", "The image index must be in hexadecimal.\n" + "No conversion will be done on the data in the DDS file.\n" + "The pixel format must be supported by the game.") { _info = info; _tag = tag; _bitmap = bitmap; }
public void ExtractDds(Bitmap bitmap, int imageIndex, Stream outStream) { // TODO: Make sure 3D textures and cube maps work // Deserialize the resource definition and verify it var resource = bitmap.Resources[imageIndex]; var resourceContext = new ResourceSerializationContext(resource.Resource); var definition = TagDeserializer.Deserialize<BitmapTextureResourceDefinition>(resourceContext); if (definition.Texture == null || definition.Texture.Definition == null) throw new ArgumentException("Invalid bitmap definition"); var dataReference = definition.Texture.Definition.Data; if (dataReference.Address.Type != ResourceAddressType.Resource) throw new InvalidOperationException("Invalid resource data address"); var header = CreateDdsHeader(definition); var resourceDataStream = new MemoryStream(); _resourceManager.Extract(resource.Resource, resourceDataStream); header.WriteTo(outStream); resourceDataStream.Position = dataReference.Address.Offset; StreamUtil.Copy(resourceDataStream, outStream, dataReference.Size); }
public static void Populate(CommandContext context, OpenTagCache info, TagInstance tag, Bitmap bitmap) { context.AddCommand(new ImportCommand(info, tag, bitmap)); }
public static CommandContext Create(CommandContext parent, OpenTagCache info, HaloTag tag, Bitmap bitmap) { var context = new CommandContext(parent, string.Format("{0:X8}.bitm", tag.Index)); context.AddCommand(new BitmImportCommand(info, tag, bitmap)); return context; }
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; }
public override bool Execute(List<string> args) { if (args.Count != 2) return false; int imageIndex; if (!int.TryParse(args[0], NumberStyles.HexNumber, null, out imageIndex)) return false; if (imageIndex < 0 || imageIndex >= Definition.Images.Count) { Console.WriteLine("Invalid image index."); return true; } var imagePath = args[1]; Console.WriteLine("Loading resource caches..."); var resourceManager = new ResourceDataManager(); try { resourceManager.LoadCachesFromDirectory(Info.CacheFile.DirectoryName); } catch { Console.WriteLine("Unable to load the resource .dat files."); Console.WriteLine("Make sure that they all exist and are valid."); return true; } Console.WriteLine("Importing image data..."); try { Definition = new Bitmap { Flags = Bitmap.RuntimeFlags.UseResource, Sequences = new List<Bitmap.Sequence> { new Bitmap.Sequence { FirstBitmapIndex = 0, BitmapCount = 1 } }, Images = new List<Bitmap.Image> { new Bitmap.Image { Signature = new Tag("bitm").Value, Unknown28 = -1 } }, Resources = new List<Bitmap.BitmapResource> { new Bitmap.BitmapResource() } }; using (var imageStream = File.OpenRead(imagePath)) { var injector = new BitmapDdsInjector(resourceManager); injector.InjectDds(Info.Serializer, Info.Deserializer, Definition, imageIndex, imageStream); } using (var tagsStream = Info.OpenCacheReadWrite()) { var tagContext = new TagSerializationContext(tagsStream, Info.Cache, Info.StringIds, Tag); Info.Serializer.Serialize(tagContext, Definition); } } catch (Exception ex) { Console.WriteLine("Importing image data failed: " + ex.Message); return true; } Console.WriteLine("Done!"); return true; }