From dad8ab6c13c00ba4bd9a8110dce3ee8988bc59fa Mon Sep 17 00:00:00 2001 From: Wardog Date: Sat, 10 Feb 2024 04:20:02 -0600 Subject: [PATCH] Add project files. --- edds2png.sln | 25 +++ edds2png/App.config | 14 ++ edds2png/BulkConverter.cs | 185 +++++++++++++++++++++ edds2png/FodyWeavers.xml | 3 + edds2png/Program.cs | 39 +++++ edds2png/Properties/AssemblyInfo.cs | 35 ++++ edds2png/edds2png.csproj | 241 ++++++++++++++++++++++++++++ edds2png/icon.ico | Bin 0 -> 2238 bytes edds2png/packages.config | 57 +++++++ 9 files changed, 599 insertions(+) create mode 100644 edds2png.sln create mode 100644 edds2png/App.config create mode 100644 edds2png/BulkConverter.cs create mode 100644 edds2png/FodyWeavers.xml create mode 100644 edds2png/Program.cs create mode 100644 edds2png/Properties/AssemblyInfo.cs create mode 100644 edds2png/edds2png.csproj create mode 100644 edds2png/icon.ico create mode 100644 edds2png/packages.config diff --git a/edds2png.sln b/edds2png.sln new file mode 100644 index 0000000..f9a49f9 --- /dev/null +++ b/edds2png.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34330.188 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "edds2png", "edds2png\edds2png.csproj", "{8474C64F-E0B6-4325-B4B1-D38189307EAF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {8474C64F-E0B6-4325-B4B1-D38189307EAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8474C64F-E0B6-4325-B4B1-D38189307EAF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8474C64F-E0B6-4325-B4B1-D38189307EAF}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8474C64F-E0B6-4325-B4B1-D38189307EAF}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4B5C2DF4-918F-424D-A103-32FF6BB36699} + EndGlobalSection +EndGlobal diff --git a/edds2png/App.config b/edds2png/App.config new file mode 100644 index 0000000..91126fc --- /dev/null +++ b/edds2png/App.config @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/edds2png/BulkConverter.cs b/edds2png/BulkConverter.cs new file mode 100644 index 0000000..2387300 --- /dev/null +++ b/edds2png/BulkConverter.cs @@ -0,0 +1,185 @@ +using K4os.Compression.LZ4.Encoders; +using Pfim; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Text; + +namespace edds2png +{ + internal class BulkConverter + { + private readonly List _imagePaths; + + public BulkConverter() + { + _imagePaths = new List(); + } + + public void Add(string path) + { + if (string.IsNullOrEmpty(path)) + { + return; + } + + if (!path.EndsWith(".edds", StringComparison.OrdinalIgnoreCase)) + { + return; + } + + _imagePaths.Add(path); + } + + public void Process() + { + List conversionExceptions = new List(); + foreach (var imagePath in _imagePaths.AsEnumerable()) + { + try + { + string fullPath = Path.GetFullPath(imagePath); + Convert(fullPath); + + Console.WriteLine($"{fullPath} -> {Path.ChangeExtension(fullPath, ".png")}"); + } + catch (Exception inner) + { + conversionExceptions.Add(inner); + } + } + + if (conversionExceptions.Count != 0) + { + throw new AggregateException(conversionExceptions); + } + } + + public bool CanProcess() + { + return _imagePaths.Count != 0; + } + + private static unsafe void Convert(string imagePath) + { + using (var stream = DecompressEDDS(imagePath)) + { + using (var image = Pfimage.FromStream(stream)) + { + PixelFormat format; + switch (image.Format) + { + case Pfim.ImageFormat.Rgba32: + { + format = PixelFormat.Format32bppArgb; + break; + } + default: + { + throw new NotImplementedException(); + } + } + + + var handle = GCHandle.Alloc(image.Data, GCHandleType.Pinned); + try + { + var data = Marshal.UnsafeAddrOfPinnedArrayElement(image.Data, 0); + var bitmap = new Bitmap(image.Width, image.Height, image.Stride, format, data); + bitmap.Save(Path.ChangeExtension(imagePath, ".png"), System.Drawing.Imaging.ImageFormat.Png); + } + finally + { + handle.Free(); + } + } + } + } + + private static MemoryStream DecompressEDDS(string imagePath) + { + List copyBlocks = new List(); + List lz4Blocks = new List(); + List decodedBlocks = new List(); + + void FindBlocks(BinaryReader reader) + { + while (true) + { + byte[] blocks = reader.ReadBytes(4); + char[] dd = Encoding.UTF8.GetChars(blocks); + + string block = new string(dd); + int size = reader.ReadInt32(); + + switch (block) + { + case "COPY": copyBlocks.Add(size); break; + case "LZ4 ": lz4Blocks.Add(size); break; + default: reader.BaseStream.Seek(-8, SeekOrigin.Current); return; + } + } + } + + using (var reader = new BinaryReader(File.Open(imagePath, FileMode.Open))) + { + byte[] dds_header = reader.ReadBytes(128); + byte[] dds_header_dx10 = null; + + if (dds_header[84] == 'D' && dds_header[85] == 'X' && dds_header[86] == '1' && dds_header[87] == '0') + { + dds_header_dx10 = reader.ReadBytes(20); + } + + FindBlocks(reader); + + foreach (int count in copyBlocks) + { + byte[] buff = reader.ReadBytes(count); + decodedBlocks.InsertRange(0, buff); + } + + foreach (int Length in lz4Blocks) + { + LZ4ChainDecoder lz4ChainDecoder = new LZ4ChainDecoder(65536, 0); + uint size = reader.ReadUInt32(); + byte[] target = new byte[size]; + + int num = 0; + int count1 = 0; + int idx = 0; + for (; num < Length - 4; num += count1 + 4) + { + count1 = reader.ReadInt32() & int.MaxValue; + byte[] numArray = reader.ReadBytes(count1); + byte[] buffer = new byte[65536]; + LZ4EncoderExtensions.DecodeAndDrain(lz4ChainDecoder, numArray, 0, count1, buffer, 0, 65536, out int count2); + + Array.Copy(buffer, 0, target, idx, count2); + idx += count2; + } + + decodedBlocks.InsertRange(0, target); + } + + if (dds_header_dx10 != null) + { + decodedBlocks.InsertRange(0, dds_header_dx10); + } + + decodedBlocks.InsertRange(0, dds_header); + byte[] final = decodedBlocks.ToArray(); + + MemoryStream stream = new MemoryStream(); + stream.Write(final, 0, final.Length); + stream.Position = 0; + + return stream; + } + } + } +} diff --git a/edds2png/FodyWeavers.xml b/edds2png/FodyWeavers.xml new file mode 100644 index 0000000..5029e70 --- /dev/null +++ b/edds2png/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/edds2png/Program.cs b/edds2png/Program.cs new file mode 100644 index 0000000..ab3fd08 --- /dev/null +++ b/edds2png/Program.cs @@ -0,0 +1,39 @@ +using System; +using System.IO; + +namespace edds2png +{ + internal class Program + { + static void Main(string[] args) + { + Console.Title = "edds2png"; + var converter = new BulkConverter(); + + foreach (var arg in args) + { + if (Directory.Exists(arg)) + { + var files = Directory.EnumerateFiles(arg, "*.edds", SearchOption.TopDirectoryOnly); + foreach (var file in files) + { + converter.Add(file); + } + } + else + { + converter.Add(arg); + } + } + + if (converter.CanProcess()) + { + converter.Process(); + + Console.Write(Environment.NewLine); + Console.Write("Press ENTER to exit..."); + while (Console.ReadKey(true).Key != ConsoleKey.Enter) { }; + } + } + } +} diff --git a/edds2png/Properties/AssemblyInfo.cs b/edds2png/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..1af0315 --- /dev/null +++ b/edds2png/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System; +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("edds2png")] +[assembly: AssemblyDescription("Converts Bohemia edds to png")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Wardog (wrdg)")] +[assembly: AssemblyProduct("edds2png")] +[assembly: AssemblyCopyright("Copyright © 2024")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("8474c64f-e0b6-4325-b4b1-d38189307eaf")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("2024.2.10.0410")] diff --git a/edds2png/edds2png.csproj b/edds2png/edds2png.csproj new file mode 100644 index 0000000..ce31623 --- /dev/null +++ b/edds2png/edds2png.csproj @@ -0,0 +1,241 @@ + + + + + + Debug + AnyCPU + {8474C64F-E0B6-4325-B4B1-D38189307EAF} + Exe + edds2png + edds2png + v4.8 + 512 + true + true + + + + AnyCPU + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + true + + + AnyCPU + none + true + bin\Release\ + TRACE + prompt + 4 + true + .pdb + + + icon.ico + + + + ..\packages\Costura.Fody.5.7.0\lib\netstandard1.0\Costura.dll + + + ..\packages\K4os.Compression.LZ4.1.3.6\lib\net462\K4os.Compression.LZ4.dll + + + ..\packages\Microsoft.Win32.Primitives.4.3.0\lib\net46\Microsoft.Win32.Primitives.dll + True + True + + + ..\packages\Pfim.0.11.2\lib\netstandard2.0\Pfim.dll + + + + ..\packages\System.AppContext.4.3.0\lib\net463\System.AppContext.dll + True + True + + + ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll + + + + ..\packages\System.Console.4.3.1\lib\net46\System.Console.dll + True + True + + + + ..\packages\System.Diagnostics.DiagnosticSource.8.0.0\lib\net462\System.Diagnostics.DiagnosticSource.dll + + + ..\packages\System.Diagnostics.Tracing.4.3.0\lib\net462\System.Diagnostics.Tracing.dll + True + True + + + + ..\packages\System.Globalization.Calendars.4.3.0\lib\net46\System.Globalization.Calendars.dll + True + True + + + ..\packages\System.IO.4.3.0\lib\net462\System.IO.dll + True + True + + + ..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll + True + True + + + + ..\packages\System.IO.Compression.ZipFile.4.3.0\lib\net46\System.IO.Compression.ZipFile.dll + True + True + + + ..\packages\System.IO.FileSystem.4.3.0\lib\net46\System.IO.FileSystem.dll + True + True + + + ..\packages\System.IO.FileSystem.Primitives.4.3.0\lib\net46\System.IO.FileSystem.Primitives.dll + True + True + + + ..\packages\System.Linq.4.3.0\lib\net463\System.Linq.dll + True + True + + + ..\packages\System.Linq.Expressions.4.3.0\lib\net463\System.Linq.Expressions.dll + True + True + + + ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll + + + ..\packages\System.Net.Http.4.3.4\lib\net46\System.Net.Http.dll + True + True + + + ..\packages\System.Net.Sockets.4.3.0\lib\net46\System.Net.Sockets.dll + True + True + + + + ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll + + + ..\packages\System.Reflection.4.3.0\lib\net462\System.Reflection.dll + True + True + + + ..\packages\System.Runtime.4.3.1\lib\net462\System.Runtime.dll + True + True + + + ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll + + + ..\packages\System.Runtime.Extensions.4.3.1\lib\net462\System.Runtime.Extensions.dll + True + True + + + ..\packages\System.Runtime.InteropServices.4.3.0\lib\net463\System.Runtime.InteropServices.dll + True + True + + + ..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll + True + True + + + ..\packages\System.Security.Cryptography.Algorithms.4.3.1\lib\net463\System.Security.Cryptography.Algorithms.dll + True + True + + + ..\packages\System.Security.Cryptography.Encoding.4.3.0\lib\net46\System.Security.Cryptography.Encoding.dll + True + True + + + ..\packages\System.Security.Cryptography.Primitives.4.3.0\lib\net46\System.Security.Cryptography.Primitives.dll + True + True + + + ..\packages\System.Security.Cryptography.X509Certificates.4.3.2\lib\net461\System.Security.Cryptography.X509Certificates.dll + True + True + + + ..\packages\System.Text.RegularExpressions.4.3.1\lib\net463\System.Text.RegularExpressions.dll + True + True + + + + + + + + ..\packages\System.Xml.ReaderWriter.4.3.1\lib\net46\System.Xml.ReaderWriter.dll + True + True + + + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + Properties\AssemblyInfo.cs + $([System.IO.File]::ReadAllText($(AssemblyInfo))) + (\[\s*assembly\s*:\s*AssemblyVersion\(\s*"(\d+)\.(\d+)\.(\d+)(\.)(\d+)("\)\s*\])) + $([System.Text.RegularExpressions.Regex]::Match('$(AssemblyInfoContent)', '$(VersionRegex)')) + [assembly: AssemblyVersion("$([System.DateTime]::Now.ToString("yyyy.M.d.HHmm"))")] + + + + + + diff --git a/edds2png/icon.ico b/edds2png/icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..ae7b5bf5f500e0796417ce5483e58f2db04dcaee GIT binary patch literal 2238 zcmeIz!3~2j3I3~~Rlf46b2mZ4IX2YN? z^3oa8cRsJ;V#@kTLU(fB6x@{ER86wJ4k7zi%tUehz_qwAQM7;Ju6XFv{C=^^-nt9x z>piPJv*v*nUwGYLyz0!pKis61_j6ouVck71eayZaF3iQFc=O2I<;I?s`|Xtf|2`h* TY#}G0`#d{4aoIS-c42%1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file