public void WriteToStream(Stream stream) { Contract.Requires <FileNotLoadedException>(Loaded); Contract.Requires <ArgumentNullException>(stream != null); Contract.Requires <ArgumentException>(stream.CanWrite); Contract.Requires <ArgumentException>(stream.CanSeek); Contract.Requires <InvalidCompressionMethodException>(Compression == CompressionAlgorithm.None, "Compressing is not yet supported !"); Contract.Requires <InvalidCompressionMethodException>(Compression == CompressionAlgorithm.None ? Versions[Version] == CompressionState.Both || Versions[Version] == CompressionState.UncompressedOnly : Versions[Version] == CompressionState.Both || Versions[Version] == CompressionState.CompressedOnly); var origin = stream.Position; using (var writer = new EndianBinaryWriter(stream, new UTF8Encoding(false, true), false, IsLittleEndian)) { writer.Write('T', 'I', 'D'); writer.Write(Version); stream.Seek(0x04, SeekOrigin.Current); writer.Write(0x80); writer.Write(0x01); writer.Write(0x01); writer.Write(0x20); stream.Seek(0x20 + origin, SeekOrigin.Begin); writer.Write(Filename.GetCustomLength(0x20)); writer.Write(0x60); writer.Write(Width); writer.Write(Height); writer.Write(Compression == CompressionAlgorithm.None ? 0x20 : 0x00); // TODO : Understand and write correct data for offset 0x50 writer.Write(0x010001); stream.Seek(0x04, SeekOrigin.Current); var bitmapData = Bitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); var data = new byte[Width * Height * 4]; Marshal.Copy(bitmapData.Scan0, data, 0, bitmapData.Width * bitmapData.Height * 4); Bitmap.UnlockBits(bitmapData); if (Compression == CompressionAlgorithm.None) { if (Version == 0x9A) { } else if ((Version & 0x02) == 0x02) { data = BitmapArrayTools.Swap32BppColorChannels(data, 3, 2, 1, 0); } else { data = BitmapArrayTools.Swap32BppColorChannels(data, 2, 1, 0, 3); } } else { data = BitmapArrayTools.Swap32BppColorChannels(data, 2, 1, 0, 3); data = Squish.CompressImage(data, Width, Height, Compression.ToSquishFlags()); // TODO : This line throws a FatalExecutionEngineError for an unknown reason } writer.Write(data.Length); writer.Write(0x80); writer.Write(Compression == CompressionAlgorithm.None ? 0x00 : 0x04); if (Compression == CompressionAlgorithm.Dxt1) { writer.Write(827611204); } else if (Compression == CompressionAlgorithm.Dxt5) { writer.Write(894720068); } else { writer.Write(0x00); } // TODO : Understand and write correct data for offsets 0x68 and 0x78 stream.Seek(0x78 + origin, SeekOrigin.Begin); writer.Write(0x101); stream.Seek(0x80 + origin, SeekOrigin.Begin); writer.Write(data); int fileSize = (int)stream.Position; stream.Seek(0x04 + origin, SeekOrigin.Begin); writer.Write(Compression == CompressionAlgorithm.None ? fileSize : 0x80); } }