private static void ExtractImage(ulong imageKey, string dpath, Dictionary <ulong, Record> map, CASCHandler handler, bool quiet, string name = null) { ulong imageDataKey = (imageKey & 0xFFFFFFFFUL) | 0x100000000UL | 0x0320000000000000UL; if (string.IsNullOrWhiteSpace(name)) { name = $"{GUID.LongKey(imageKey):X12}"; } string path = $"{dpath}{name}.dds"; if (!Directory.Exists(Path.GetDirectoryName(path))) { Directory.CreateDirectory(Path.GetDirectoryName(path)); } using (Stream outp = File.Open(path, FileMode.Create, FileAccess.Write)) { if (map.ContainsKey(imageDataKey)) { Texture tex = new Texture(Util.OpenFile(map[imageKey], handler), Util.OpenFile(map[imageDataKey], handler)); tex.Save(outp); } else { TextureLinear tex = new TextureLinear(Util.OpenFile(map[imageKey], handler)); tex.Save(outp); } } if (!quiet) { Console.Out.WriteLine("Wrote image {0}", path); } }
public static void Save(ulong key, string path, Dictionary <ulong, Record> map, bool quiet, CASCHandler handler) { if (!map.ContainsKey(key)) { return; } if (!Directory.Exists(Path.GetDirectoryName(path))) { Directory.CreateDirectory(Path.GetDirectoryName(path)); } ulong imageDataKey = (key & 0xFFFFFFFFUL) | 0x100000000UL | 0x0320000000000000UL; using (Stream outp = File.Open(path, FileMode.Create, FileAccess.Write)) { if (map.ContainsKey(imageDataKey)) { Texture tex = new Texture(Util.OpenFile(map[key], handler), Util.OpenFile(map[imageDataKey], handler)); tex.Save(outp); } else { TextureLinear tex = new TextureLinear(Util.OpenFile(map[key], handler)); tex.Save(outp); } } if (!quiet) { Console.Out.WriteLine("Wrote portrait {0}", path); } }
public override void Run(WorkerThread thread) { const string convertType = "tif"; Stream headerStream = OpenFile(HeaderGUID); Stream dataStream = null; if (DataGUID != 0) { dataStream = OpenFile(DataGUID); } string filePath = System.IO.Path.Combine(Path, $"{GUID.Index(HeaderGUID)}"); CreateDirectoryFromFile(filePath); TextureHeader header; Stream convertedStream; if (dataStream != null) { Texture textObj = new Texture(headerStream, dataStream); convertedStream = textObj.Save(); header = textObj.Header; headerStream.Dispose(); dataStream.Dispose(); } else { TextureLinear textObj = new TextureLinear(headerStream); convertedStream = textObj.Save(); header = textObj.Header; headerStream.Dispose(); } uint fourCC = header.Format().ToPixelFormat().fourCC; bool isBcffValid = Combo.TextureConfig.DXGI_BC4.Contains((int)header.format) || Combo.TextureConfig.DXGI_BC5.Contains((int)header.format) || fourCC == Combo.TextureConfig.FOURCC_ATI1 || fourCC == Combo.TextureConfig.FOURCC_ATI2; ImageFormat imageFormat = null; if (convertType == "tif") { imageFormat = ImageFormat.Tiff; } convertedStream.Position = 0; if (isBcffValid && imageFormat != null && convertedStream.Length != 0) { BlockDecompressor decompressor = new BlockDecompressor(convertedStream); decompressor.CreateImage(); decompressor.Image.Save($"{filePath}.{convertType}", imageFormat); return; } convertedStream.Position = 0; if (convertType == "tga" || convertType == "tif" || convertType == "dds") { // we need the dds for tif conversion WriteFile(convertedStream, $"{filePath}.dds"); } convertedStream.Close(); if (convertType != "tif" && convertType != "tga") { return; } Process pProcess = new Process { StartInfo = { FileName = "Third Party\\texconv.exe", UseShellExecute = false, RedirectStandardOutput = true, Arguments = $"\"{filePath}.dds\" -y -wicmulti -nologo -m 1 -ft {convertType} -f R8G8B8A8_UNORM -o \"{Path}" } }; // -wiclossless? // erm, so if you add an end quote to this then it breaks. // but start one on it's own is fine (we need something for "Winged Victory") pProcess.Start(); // pProcess.WaitForExit(); // not using this is kinda dangerous but I don't care // when texconv writes with to the console -nologo is has done/failed conversion // string line = pProcess.StandardOutput.ReadLine(); // if (line?.Contains($"{filePath}.dds FAILED") == false) { // fallback if convert fails File.Delete($"{filePath}.dds"); // } }
public static void Extract(STUD itemStud, string output, string heroName, string itemName, string itemGroup, Dictionary <ushort, List <ulong> > track, Dictionary <ulong, Record> map, CASCHandler handler, bool quiet, OverToolFlags flags) { string path = string.Format("{0}{1}{2}{1}{3}{1}{5}{1}{4}.dds", output, Path.DirectorySeparatorChar, Util.Strip(Util.SanitizePath(heroName)), Util.SanitizePath(itemStud.Instances[0].Name), Util.SanitizePath(itemName), Util.SanitizePath(itemGroup)); if (itemStud.Instances == null) { return; } IconItem item = (IconItem)itemStud.Instances[0]; if (item == null) { return; } if (!map.ContainsKey(item.Data.decal.key)) { return; } STUD decalStud = new STUD(Util.OpenFile(map[item.Data.decal.key], handler)); if (decalStud.Instances == null) { return; } Decal decal = (Decal)decalStud.Instances[0]; if (decal == null) { return; } if (!map.ContainsKey(decal.Records[0].definiton.key)) { return; } ImageDefinition definition = new ImageDefinition(Util.OpenFile(map[decal.Records[0].definiton.key], handler)); ulong imageKey = definition.Layers[0].Key; if (!map.ContainsKey(imageKey)) { return; } if (!Directory.Exists(Path.GetDirectoryName(path))) { Directory.CreateDirectory(Path.GetDirectoryName(path)); } ulong imageDataKey = (imageKey & 0xFFFFFFFFUL) | 0x100000000UL | 0x0320000000000000UL; using (Stream outp = File.Open(path, FileMode.Create, FileAccess.Write)) { if (map.ContainsKey(imageDataKey)) { Texture tex = new Texture(Util.OpenFile(map[imageKey], handler), Util.OpenFile(map[imageDataKey], handler)); tex.Save(outp); } else { TextureLinear tex = new TextureLinear(Util.OpenFile(map[imageKey], handler)); tex.Save(outp); } } if (!quiet) { Console.Out.WriteLine("Wrote icon {0}", path); } }
private static void ConvertTexture(string convertType, string filePath, string path, Stream headerStream, Stream dataStream) { CreateDirectoryFromFile(path); Stream convertedStream; TextureHeader header; if (dataStream != null) { Texture textObj = new Texture(headerStream, dataStream); convertedStream = textObj.Save(); header = textObj.Header; headerStream.Dispose(); dataStream.Dispose(); } else { TextureLinear textObj = new TextureLinear(headerStream); convertedStream = textObj.Save(); header = textObj.Header; headerStream.Dispose(); } uint fourCC = header.Format().ToPixelFormat().fourCC; bool isBcffValid = TextureConfig.DXGI_BC4.Contains((int)header.format) || TextureConfig.DXGI_BC5.Contains((int)header.format) || fourCC == TextureConfig.FOURCC_ATI1 || fourCC == TextureConfig.FOURCC_ATI2; ImageFormat imageFormat = null; if (convertType == "tif") { imageFormat = ImageFormat.Tiff; } // if (convertType == "tga") imageFormat = Im.... oh // so there is no TGA image format. // guess the TGA users are stuck with the DirectXTex stuff for now. if (convertedStream.Length == 0) { WriteFile(Stream.Null, $"{filePath}.{convertType}"); return; } convertedStream.Position = 0; if (isBcffValid && imageFormat != null) { BlockDecompressor decompressor = new BlockDecompressor(convertedStream); decompressor.CreateImage(); decompressor.Image.Save($"{filePath}.{convertType}", imageFormat); return; } convertedStream.Position = 0; if (convertType == "tga" || convertType == "tif" || convertType == "dds") { // we need the dds for tif conversion WriteFile(convertedStream, $"{filePath}.dds"); } convertedStream.Close(); if (convertType != "tif" && convertType != "tga") { return; } Process pProcess = new Process { StartInfo = { FileName = "Third Party\\texconv.exe", UseShellExecute = false, RedirectStandardOutput = true, Arguments = $"\"{filePath}.dds\" -y -wicmulti -nologo -m 1 -ft {convertType} -f R8G8B8A8_UNORM -o \"{path}" } }; // -wiclossless? // erm, so if you add an end quote to this then it breaks. // but start one on it's own is fine (we need something for "Winged Victory") pProcess.Start(); // pProcess.WaitForExit(); // not using this is kinda dangerous but I don't care // when texconv writes with to the console -nologo is has done/failed conversion string line = pProcess.StandardOutput.ReadLine(); if (line?.Contains($"{filePath}.dds FAILED") == false) { // fallback if convert fails File.Delete($"{filePath}.dds"); } }
public Recursive(string destFile, string f004, string f04D) { dDest = destFile; d004 = f004; d04D = f04D; string[] f004s = Directory.GetFiles(d004, "*.004"); foreach (string f004i in f004s) { try { using (Stream s004 = File.Open(f004i, FileMode.Open, FileAccess.Read)) { TextureLinear master = new TextureLinear(s004, true); string fn004 = Path.GetFileNameWithoutExtension(f004i); Console.Out.WriteLine("Opened Texture {0}. W: {1} H: {2} F: {3} M: {4} S: {5} T: {6}", fn004, master.Header.width, master.Header.height, master.Format.ToString(), master.Header.mips, master.Header.surfaces, master.Header.type); string ntype = "004"; if (master.Loaded == false && d04D == null) { Console.Error.WriteLine("Missing 04D texture"); continue; } if (master.Header.IsCubemap()) { ntype = "cube"; } else if (master.Header.surfaces > 1) { ntype = "multisurface"; } else if (master.Loaded == false) { ntype = "04D"; } string nindex = fn004.Substring(fn004.Length - 12, 4); string nDDS = string.Format("{0}{1}{3}{1}{4}{1}{2}.dds", dDest, Path.DirectorySeparatorChar, fn004, ntype, nindex); string nDDSd = Path.GetDirectoryName(nDDS); if (!Directory.Exists(nDDSd)) { Directory.CreateDirectory(nDDSd); } using (Stream sDDS = File.Open(nDDS, FileMode.Create, FileAccess.Write)) { if (master.Loaded == false) { string fn04D = (master.Header.indice - 1).ToString("X").PadLeft(fn004.Length - 8, '0') + fn004.Substring(fn004.Length - 8); // try to find the texture string f04Di = $"{d04D}{Path.DirectorySeparatorChar}{fn04D}.04D"; if (d04D == null || !File.Exists(f04Di)) { Console.Error.WriteLine("Corresponding 04D {1} file for 004 {0} does not exist", fn004, fn04D); continue; } s004.Position = 0; using (Stream s04D = File.Open(f04Di, FileMode.Open, FileAccess.Read)) { Texture tex = new Texture(s004, s04D); Console.Out.WriteLine("Opened Texture Data {0}. M: {1} S: {2}", fn004, tex.RawHeader.mips, tex.RawHeader.surfaces); tex.Save(sDDS); Console.Out.WriteLine("Converted texture pair {0}.dds", fn004); } } else { master.Save(sDDS); Console.Out.WriteLine("Converted texture {0}.dds", fn004); } } } } catch (Exception ex) { Console.Error.WriteLine("Failed to convert texture."); Console.Error.WriteLine(ex.ToString()); } } }
static void Main(string[] args) { if (args.Length < 3) { Console.Out.WriteLine("Usage: TextureTool.exe mode 004 04D\n\nExamples:"); Console.Out.WriteLine("TextureTool.exe output_folder r 004_directory 04D_directory\n\t(04D_directory is optional)"); Console.Out.WriteLine("TextureTool.exe output_file 2 004_file 04D_file"); Console.Out.WriteLine("TextureTool.exe output_file 1 004_file"); return; } Console.Out.WriteLine("{0} v{1}", Assembly.GetExecutingAssembly().GetName().Name, OWLib.Util.GetVersion()); string destFile = args[0]; char mode = args[1][0]; string f004 = args[2]; string f04d = null; if (args.Length > 3) { f04d = args[3]; } if (mode == 'r') { new Recursive(destFile, f004, f04d); return; } using (Stream headerStream = File.Open(f004, FileMode.Open, FileAccess.Read)) { if (mode == '1') { TextureLinear tex = new TextureLinear(headerStream); Console.Out.WriteLine("Opened Texture. W: {0} H: {1} F: {2} M: {3} S: {4} T: {5}", tex.Header.width, tex.Header.height, tex.Format.ToString(), tex.Header.mips, tex.Header.surfaces, tex.Header.type); if (tex.Loaded == false) { Console.Error.WriteLine("Error?! (Probably unsupported format)"); return; } using (Stream stream = File.Open(destFile, FileMode.Create, FileAccess.Write)) { tex.Save(stream); } } else if (mode == '2') { using (Stream dataStream = File.Open(f04d, FileMode.Open, FileAccess.Read)) { Texture tex = new Texture(headerStream, dataStream); Console.Out.WriteLine("Opened Texture. W: {0} H: {1} F: {2} M: {3} S: {4} T: {5}", tex.Header.width, tex.Header.height, tex.Format.ToString(), tex.RawHeader.mips, tex.RawHeader.surfaces, tex.Header.type); if (tex.Loaded == false) { Console.Error.WriteLine("Error?! (Probably unsupported format)"); return; } using (Stream ddsStream = File.Open(destFile, FileMode.Create, FileAccess.Write)) { tex.Save(ddsStream); Console.Out.WriteLine("Saved DDS"); } } } } }