public static byte[] Save(TGA tga) { byte[] buffer; using (MemoryStream ms = new MemoryStream()) using (BinaryWriter bw = new BinaryWriter(ms)) { bw.Write((byte)0); // ID length bw.Write((byte)0); // Colourmap type bw.Write((byte)tga.Type); bw.Write((short)0); // Colourmap first entry bw.Write((short)0); // Colourmap length bw.Write((byte)0); // Colourmap entry size bw.Write((short)0); // X origin bw.Write((short)0); // Y origin bw.Write((short)tga.Width); bw.Write((short)tga.Height); bw.Write(tga.PixelDepth); bw.Write((byte)0); // ImageDescriptor bw.Write(tga.Data); bw.Flush(); ms.Flush(); buffer = ms.ToArray(); } return(buffer); }
public static TGA Load(Stream stream, string name = null) { TGA tga = new TGA { Name = name }; using (BinaryReader br = new BinaryReader(stream)) { byte idLength = br.ReadByte(); byte colourMapType = br.ReadByte(); tga.Type = (ImageType)br.ReadByte(); if (idLength > 0) { throw new NotImplementedException("No support for TGA files with ID sections!"); } if (colourMapType == 0) { br.ReadBytes(5); } else { throw new NotImplementedException("No support for TGA files with ColourMaps!"); } int xOrigin = br.ReadInt16(); int yOrigin = br.ReadInt16(); tga.Width = br.ReadInt16(); tga.Height = br.ReadInt16(); tga.PixelDepth = br.ReadByte(); byte imageDescriptor = br.ReadByte(); byte size = (byte)(tga.PixelDepth / 8); switch (tga.Type) { case ImageType.TrueColourRLE: tga.Data = br.ReadBytes((int)br.BaseStream.Length - 13); break; default: tga.Data = br.ReadBytes(tga.Width * tga.Height * size); break; } } return(tga); }
public static TGA FromBitmap(Bitmap bitmap) { TGA tga = new TGA { Width = bitmap.Width, Height = bitmap.Height, Type = ImageType.TrueColour, PixelDepth = 32 }; byte[] raw = new byte[bitmap.Width * bitmap.Height * 4]; BitmapData data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); Marshal.Copy(data.Scan0, raw, 0, data.Stride * data.Height); bitmap.UnlockBits(data); tga.Data = new byte[raw.Length]; using (MemoryStream ms = new MemoryStream(tga.Data)) using (BinaryWriter bw = new BinaryWriter(ms)) { for (int y = data.Height - 1; y >= 0; y--) { for (int x = 0; x < data.Width; x++) { int offset = y * data.Stride + (x * 4); bw.Write(raw[offset + 0]); bw.Write(raw[offset + 1]); bw.Write(raw[offset + 2]); bw.Write(raw[offset + 3]); } } } return(tga); }
public void SaveAs(string path, OutputFormat outputFormat) { if (Mode == 0) { switch (outputFormat) { case OutputFormat.PNG: DDS.Decompress().Save(path, ImageFormat.Png); break; case OutputFormat.DDS: DDS.Save(path); break; case OutputFormat.TGA: TGA.FromBitmap(DDS.Decompress()).Save(path); break; } } else { Raw.Save(path, ImageFormat.Png); } }
public static TGA Load(byte[] data) { TGA tga = new TGA(); using (MemoryStream ms = new MemoryStream(data)) using (BinaryReader br = new BinaryReader(ms)) { BitmapData bmpdata; PixelFormat format = PixelFormat.Format32bppArgb; byte idLength = br.ReadByte(); byte colourMapType = br.ReadByte(); byte imageType = br.ReadByte(); if (idLength > 0) { throw new NotImplementedException("No support for TGA files with ID sections!"); } if (colourMapType == 0) { br.ReadBytes(5); } else { throw new NotImplementedException("No support for TGA files with ColourMaps!"); } int xOrigin = br.ReadInt16(); int yOrigin = br.ReadInt16(); int width = br.ReadInt16(); int height = br.ReadInt16(); byte pixelDepth = br.ReadByte(); byte size = (byte)(pixelDepth / 8); byte imageDescriptor = br.ReadByte(); if (size == 3) { format = PixelFormat.Format24bppRgb; } tga.bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); bmpdata = tga.bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, format); if (imageType == 10) { const int iRAWSection = 127; uint j = 0; int iStep = 0; int bpCount = 0; int currentPixel = 0; int pixelCount = width * height; var colorBuffer = new byte[size]; byte chunkHeader = 0; byte[] buffer = br.ReadBytes((int)br.BaseStream.Length - 13); using (var nms = new MemoryStream()) { while (currentPixel < pixelCount) { chunkHeader = buffer[iStep]; iStep++; if (chunkHeader <= iRAWSection) { chunkHeader++; bpCount = size * chunkHeader; nms.Write(buffer, iStep, bpCount); iStep += bpCount; currentPixel += chunkHeader; } else { chunkHeader -= iRAWSection; Array.Copy(buffer, iStep, colorBuffer, 0, size); iStep += size; for (j = 0; j < chunkHeader; j++) { nms.Write(colorBuffer, 0, size); } currentPixel += chunkHeader; } } var contentBuffer = new byte[nms.Length]; nms.Position = 0; nms.Read(contentBuffer, 0, contentBuffer.Length); Marshal.Copy(contentBuffer, 0, bmpdata.Scan0, contentBuffer.Length); } } else { Marshal.Copy(br.ReadBytes(width * height * size), 0, bmpdata.Scan0, width * height * size); } tga.bitmap.UnlockBits(bmpdata); } return tga; }
private static string processFile(string path) { BMAP bmap = new BMAP(); string extension = Path.GetExtension(path).Substring(1); string outputName; if (settings.Raw) { if (Raw.IsValid(path)) { Console.WriteLine($"Loading : {Path.GetFileName(path)}"); Raw.Load(path, true); return(path); } } else if (settings.Compress) { if (Enum.TryParse(extension, out WreckfestExtensions we)) { using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(path))) using (BinaryReader br = new BinaryReader(ms)) { if ( br.ReadInt32() != 4 || br.ReadByte() != extension[3] || br.ReadByte() != extension[2] || br.ReadByte() != extension[1] || br.ReadByte() != extension[0]) { br.BaseStream.Position = 0; byte[] input = br.ReadBytes((int)ms.Length); File.Move(path, $"{path}.bak"); using (BinaryWriter bw = new BinaryWriter(new FileStream(path, FileMode.Create))) { bw.Write(4); bw.Write(extension[3]); bw.Write(extension[2]); bw.Write(extension[1]); bw.Write(extension[0]); bw.Write((int)we); int[] hashTable = new int[1 << (14 - 2)]; byte[] output = new byte[LZ4Compress.CalculateChunkSize(input.Length)]; int i = 0; while (i < input.Length) { byte[] chunk = new byte[Math.Min(input.Length - i, output.Length)]; Array.Copy(input, i, chunk, 0, chunk.Length); Array.Clear(hashTable, 0, hashTable.Length); int size = LZ4Compress.Compress(hashTable, chunk, output, chunk.Length, chunk.Length + 4); bw.Write(size); bw.Write(output, 0, size); i += chunk.Length; } } } else { Console.WriteLine($"Skipping : {Path.GetFileName(path)} is already compressed"); } } } else { Console.WriteLine($"Error : unsupported extension '{extension}'."); } } else if (extension == "bmap") { if (BMAP.IsBMAP(path)) { Console.WriteLine($"Loading : {Path.GetFileName(path)}"); bmap = BMAP.Load(path, false); outputName = $"{Path.GetFileNameWithoutExtension(path)}.{(bmap.Mode == 1 ? "clutter" : (bmap.DDS.Format == D3DFormat.A8R8G8B8 ? "raw" : bmap.DDS.Format.ToString().ToLower()))}.{settings.SaveAs}"; Console.WriteLine($"Saving : {outputName}"); if (!overwrite($@"{Path.GetDirectoryName(path)}\{outputName}")) { return(null); } bmap.SaveAs(outputName, settings.SaveAs); return(path); } } else if (extension == "dds") { string newExtension = $"{(settings.NoRename ? "" : ".x")}.bmap"; Console.WriteLine($"Loading : {Path.GetFileName(path)}"); Console.WriteLine($"Saving : {Path.GetFileNameWithoutExtension(path)}{newExtension}"); bmap.Path = Path.GetFileName(path); bmap.DDS = DDS.Load(path); if (!overwrite(path.Replace(".dds", newExtension))) { return(null); } bmap.Save(path.Replace(".dds", newExtension)); return(path); } else if (Array.IndexOf(new string[] { "png", "tga", "tif" }, extension) > -1) { Texture texture = null; Console.WriteLine($"Loading : {Path.GetFileName(path)}"); switch (extension) { case "tga": texture = TGA.Load(path); break; case "tif": case "png": texture = Texture.Load(path); break; } BreckfestSettings original = settings.Clone(); if (Path.GetFileNameWithoutExtension(path).EndsWith(".clutter", StringComparison.OrdinalIgnoreCase)) { settings.Clutter = true; path = path.Replace(".clutter", ""); } else if (Path.GetFileNameWithoutExtension(path).EndsWith(".raw", StringComparison.OrdinalIgnoreCase)) { settings.Format = D3DFormat.A8R8G8B8; path = path.Replace(".raw", ""); } else if (Path.GetFileNameWithoutExtension(path).EndsWith(".dxt1", StringComparison.OrdinalIgnoreCase)) { settings.Format = D3DFormat.DXT1; path = path.Replace(".dxt1", ""); } else if (Path.GetFileNameWithoutExtension(path).EndsWith(".dxt5", StringComparison.OrdinalIgnoreCase)) { settings.Format = D3DFormat.DXT5; path = path.Replace(".dxt5", ""); } bmap.Path = Path.GetFileName(path); if (settings.Clutter) { Console.WriteLine($"Cluttering: {texture.Bitmap.Width}x{texture.Bitmap.Height}"); bmap.Mode = 1; bmap.Raw = texture.Bitmap; } else { if (settings.Format == D3DFormat.A8R8G8B8) { Console.WriteLine($"Formatting: {texture.Bitmap.Width}x{texture.Bitmap.Height} (this might take awhile)"); } else { Console.WriteLine($"Squishing : {texture.Bitmap.Width}x{texture.Bitmap.Height} (this might take awhile)"); } bmap.DDS = new DDS(settings.Format, texture.Bitmap); } string newExtension = $"{(settings.NoRename ? "" : ".x")}.bmap"; Console.WriteLine($"Saving : {Path.GetFileNameWithoutExtension(path)}{newExtension}"); if (!overwrite(path.Replace($".{extension}", $"{newExtension}"))) { return(null); } bmap.Save(path.Replace($".{extension}", $"{newExtension}"), true); settings = original.Clone(); return(path); } return(null); }
public static TGA Load(byte[] data) { TGA tga = new TGA(); using (MemoryStream ms = new MemoryStream(data)) using (BinaryReader br = new BinaryReader(ms)) { BitmapData bmpdata; PixelFormat format = PixelFormat.Format32bppArgb; byte idLength = br.ReadByte(); byte colourMapType = br.ReadByte(); byte imageType = br.ReadByte(); if (idLength > 0) { throw new NotImplementedException("No support for TGA files with ID sections!"); } if (colourMapType == 0) { br.ReadBytes(5); } else { throw new NotImplementedException("No support for TGA files with ColourMaps!"); } int xOrigin = br.ReadInt16(); int yOrigin = br.ReadInt16(); int width = br.ReadInt16(); int height = br.ReadInt16(); byte pixelDepth = br.ReadByte(); byte size = (byte)(pixelDepth / 8); byte imageDescriptor = br.ReadByte(); if (size == 3) { format = PixelFormat.Format24bppRgb; } tga.bitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb); bmpdata = tga.bitmap.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, format); if (imageType == 10) { const int iRAWSection = 127; uint j = 0; int iStep = 0; int bpCount = 0; int currentPixel = 0; int pixelCount = width * height; var colorBuffer = new byte[size]; byte chunkHeader = 0; byte[] buffer = br.ReadBytes((int)br.BaseStream.Length - 13); using (var nms = new MemoryStream()) { while (currentPixel < pixelCount) { chunkHeader = buffer[iStep]; iStep++; if (chunkHeader <= iRAWSection) { chunkHeader++; bpCount = size * chunkHeader; nms.Write(buffer, iStep, bpCount); iStep += bpCount; currentPixel += chunkHeader; } else { chunkHeader -= iRAWSection; Array.Copy(buffer, iStep, colorBuffer, 0, size); iStep += size; for (j = 0; j < chunkHeader; j++) { nms.Write(colorBuffer, 0, size); } currentPixel += chunkHeader; } } var contentBuffer = new byte[nms.Length]; nms.Position = 0; nms.Read(contentBuffer, 0, contentBuffer.Length); Marshal.Copy(contentBuffer, 0, bmpdata.Scan0, contentBuffer.Length); } } else { Marshal.Copy(br.ReadBytes(width * height * size), 0, bmpdata.Scan0, width * height * size); } tga.bitmap.UnlockBits(bmpdata); } return(tga); }
public static new TGA Load(string path) { return(TGA.Load(File.ReadAllBytes(path))); }