├── .gitattributes ├── .gitignore ├── DFO.Common.Tests ├── DFO.Common.Tests.csproj ├── NpkPathTestFixture.cs ├── Properties │ └── AssemblyInfo.cs ├── ScriptPvfPathTestFixture.cs └── packages.config ├── DFO.Common ├── DFO.Common.csproj ├── Images │ ├── AnimationFrame.cs │ ├── ConstAnimationFrame.cs │ ├── ConstRawAnimation.cs │ ├── FrameInfo.cs │ ├── IImageSource.cs │ ├── Image.cs │ ├── ImageIdentifier.cs │ ├── PixelDataFormat.cs │ └── RawAnimation.cs ├── NpkPath.cs ├── Properties │ └── AssemblyInfo.cs └── ScriptPvfPath.cs ├── DFO.Images ├── DFO.Images.csproj ├── Export.cs ├── GifMaker.cs ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── DFO.Npk.IntegrationTests ├── App.config ├── Config.cs ├── DFO.Npk.IntegrationTests.csproj ├── NpkReaderTestFixture.cs ├── Properties │ └── AssemblyInfo.cs ├── packages.config └── setup.txt ├── DFO.Npk ├── App.config ├── DFO.Npk.csproj ├── IReadableFrame.cs ├── NpkByteRange.cs ├── NpkEditor.cs ├── NpkException.cs ├── NpkFileTableEntry.cs ├── NpkReader.LazyFramesReadOnlyDictionary.cs ├── NpkReader.cs ├── NpkWriter.cs ├── Properties │ └── AssemblyInfo.cs ├── SoundInfo.cs └── packages.config ├── DFO.Sandbox ├── App.config ├── DFO.Sandbox.csproj ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── DFO.Utilities ├── DFO.Utilities.csproj ├── IConstable.cs ├── Properties │ └── AssemblyInfo.cs ├── UtilityExtensions.cs ├── Utils.cs └── packages.config ├── DFOToolBox.sln ├── DFOToolbox ├── AboutWindow.xaml ├── AboutWindow.xaml.cs ├── AboutWindowViewModel.cs ├── App.config ├── App.xaml ├── App.xaml.cs ├── DFOToolbox.csproj ├── DFOToolboxException.cs ├── DesignerMainWindowViewModel.cs ├── IMainWindowViewModel.cs ├── IMultiSelectCollectionView.cs ├── ISelectable.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── MainWindowViewCommands.cs ├── MainWindowViewModel.cs ├── Models │ ├── FrameList.cs │ ├── FrameMetadata.cs │ ├── InnerNpkFile.cs │ └── InnerNpkFileList.cs ├── MultiSelect.cs ├── MultiSelectCollectionView.cs ├── NotifyPropertyChangedBase.cs ├── PixelConversion.cs ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings ├── QuickSaveResults.cs ├── StrongListCollectionView.cs ├── StrongMultiSelectListCollectionView.cs └── packages.config ├── lib └── msvcp2012x86 │ ├── msvcp110.dll │ └── msvcr110.dll ├── license.txt ├── licenses ├── graphicsmagick_licenses.txt ├── graphicsmagick_net_license.txt ├── ndesk_options_license.txt ├── readme.txt └── sharpziplib_license.txt ├── npk2gif ├── App.config ├── CommandLineArgs.cs ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── npk2gif.csproj └── packages.config ├── npkdiff ├── App.config ├── CommandLineArgs.cs ├── FrameCountDifferenceInfo.cs ├── ImgInfo.cs ├── NpkDirContents.cs ├── NpkDirDifferences.cs ├── Program.cs ├── Properties │ └── AssemblyInfo.cs ├── npkdiff.csproj └── packages.config ├── packages └── repositories.config └── readme.md /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bin/ 2 | obj/ 3 | *.user 4 | *.suo 5 | packages/*/ 6 | -------------------------------------------------------------------------------- /DFO.Common.Tests/DFO.Common.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {016B332A-BEF3-496F-A896-3C5F2BC41238} 8 | Library 9 | Properties 10 | DFO.Common.Tests 11 | DFO.Common.Tests 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | true 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | true 33 | 34 | 35 | 36 | False 37 | ..\packages\NUnit.2.6.4\lib\nunit.framework.dll 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | {f96de472-94ce-46dc-89fe-049207cc9541} 51 | DFO.Common 52 | 53 | 54 | 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /DFO.Common.Tests/NpkPathTestFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using NUnit.Framework; 6 | 7 | namespace DFO.Common.Tests 8 | { 9 | [TestFixture] 10 | public class NpkPathTest 11 | { 12 | [Test] 13 | public void TestGetNpkName() 14 | { 15 | NpkPath testPath = "Interface/Emoticon/Against.img"; 16 | Assert.That(testPath.GetImageNpkName(), Is.EqualTo("sprite_Interface_Emoticon.npk")); 17 | 18 | testPath = "sprite/Interface/Emoticon/Against.img"; 19 | Assert.That(testPath.GetImageNpkName(), Is.EqualTo("sprite_Interface_Emoticon.npk")); 20 | 21 | testPath = "equip/armor/cloth_touch.wav"; 22 | Assert.That(testPath.GetSoundNpkName(), Is.EqualTo("sounds_equip_armor.npk")); 23 | 24 | testPath = "sounds/equip/armor/cloth_touch.wav"; 25 | Assert.That(testPath.GetSoundNpkName(), Is.EqualTo("sounds_equip_armor.npk")); 26 | 27 | testPath = "/"; 28 | Assert.That(testPath.GetImageNpkName(), Is.EqualTo("sprite.npk")); 29 | Assert.That(testPath.GetSoundNpkName(), Is.EqualTo("sounds.npk")); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /DFO.Common.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DFO.Common.Tests")] 9 | [assembly: AssemblyDescription("Unit tests for DFO.Common")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DFO Toolbox")] 13 | [assembly: AssemblyCopyright("Copyright © LHCGreg 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0e03ab0e-4c91-4ec8-8389-051d396459cb")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /DFO.Common.Tests/ScriptPvfPathTestFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using NUnit.Framework; 8 | 9 | namespace DFO.Common.Tests 10 | { 11 | [TestFixture] 12 | public class ScriptPvfPathTest 13 | { 14 | [Test] 15 | public void TestScriptPvfPath() 16 | { 17 | ScriptPvfPath path1 = new ScriptPvfPath("abc/def.i"); 18 | ScriptPvfPath path2 = new ScriptPvfPath("///ABc///def.I//"); 19 | ScriptPvfPath pathX = new ScriptPvfPath("///ABc///def.I//a"); 20 | ScriptPvfPath pathY = new ScriptPvfPath("abc/def.i/a"); 21 | ScriptPvfPath pathXBackslashes = new ScriptPvfPath(@"\\AbC/\/\def.i\a\"); 22 | ScriptPvfPath slashes = new ScriptPvfPath(@"//\"); 23 | ScriptPvfPath empty = new ScriptPvfPath(""); 24 | 25 | Assert.That(path1, Is.EqualTo(path2)); 26 | Assert.That(path1, Is.Not.EqualTo(pathX)); 27 | Assert.That(path1, Is.Not.EqualTo(pathY)); 28 | Assert.That(pathX, Is.EqualTo(pathXBackslashes)); 29 | Assert.That(slashes, Is.EqualTo(empty)); 30 | 31 | Assert.That(path1.GetHashCode(), Is.EqualTo(path2.GetHashCode())); 32 | } 33 | 34 | [Test] 35 | public void TestGetPathComponents() 36 | { 37 | ScriptPvfPath path1 = new ScriptPvfPath("///ABc///def.I//"); 38 | // This is actually a stricter test than it should be. The path components are not 39 | // guaranteed to be the same case as in the original string. But the test is easier to write this way. 40 | Assert.That(path1.GetPathComponents(), Is.EqualTo(new List() { "ABc", "def.I" })); 41 | 42 | ScriptPvfPath emptyPath = new ScriptPvfPath("/"); 43 | Assert.That(emptyPath.GetPathComponents(), Is.EqualTo(new List())); 44 | } 45 | 46 | [Test] 47 | public void TestGetContainingDirectory() 48 | { 49 | ScriptPvfPath path1 = new ScriptPvfPath(@"\\AbC/\/\def.i\a\"); 50 | Assert.That(path1.GetContainingDirectory(), Is.EqualTo(new ScriptPvfPath(@"abc\\def.i\\"))); 51 | 52 | ScriptPvfPath empty = new ScriptPvfPath("/"); 53 | Assert.That(empty.GetContainingDirectory(), Is.EqualTo(empty)); 54 | } 55 | 56 | [Test] 57 | public void TestGetFileName() 58 | { 59 | ScriptPvfPath path1 = new ScriptPvfPath(@"\\abc/\/def.i/a/"); 60 | Assert.That(path1.GetFileName(), Is.EqualTo(new ScriptPvfPath(@"a"))); 61 | 62 | ScriptPvfPath path2 = new ScriptPvfPath(@"abc/"); 63 | Assert.That(path2.GetFileName(), Is.EqualTo(new ScriptPvfPath(@"abc"))); 64 | 65 | ScriptPvfPath path3 = new ScriptPvfPath(@""); 66 | Assert.That(path3.GetFileName(), Is.EqualTo(new ScriptPvfPath(@""))); 67 | } 68 | 69 | //[Test] 70 | //public void TestScriptPvfPathPerf() 71 | //{ 72 | // const int numIterations = 1000000; 73 | // TimeSpan timeAllowed = new TimeSpan(0, 0, 0, 0, 500); 74 | // const string testPath = "equipment/character/gunner/weapon/bowgun/aqr.equ"; 75 | 76 | // Stopwatch timer = new Stopwatch(); 77 | // timer.Start(); 78 | // for (int i = 0; i < numIterations; i++) 79 | // { 80 | // ScriptPvfPath path = new ScriptPvfPath(testPath); 81 | // } 82 | // timer.Stop(); 83 | 84 | // Console.WriteLine("Time taken: {0}; Target time: {1}", timer.Elapsed, timeAllowed); 85 | 86 | // // Gives an "inconclusive" result if the target time wasn't met. Maybe the machine was under 87 | // // heavy load. 88 | // NUnit.Framework.Assume.That(timer.Elapsed, Is.LessThan(timeAllowed)); 89 | //} 90 | 91 | [Test] 92 | public void TestCombine() 93 | { 94 | ScriptPvfPath testPath = new ScriptPvfPath("abc/def/xyz.equ"); 95 | ScriptPvfPath path1 = new ScriptPvfPath(ScriptPvfPath.Combine("abc/def", "xyz.equ")); 96 | ScriptPvfPath path2 = new ScriptPvfPath(ScriptPvfPath.Combine("/abc/def/", "xyz.equ")); 97 | ScriptPvfPath path3 = new ScriptPvfPath(ScriptPvfPath.Combine("", "abc//def/xyz.equ")); 98 | Assert.That(path1, Is.EqualTo(testPath)); 99 | Assert.That(path2, Is.EqualTo(testPath)); 100 | Assert.That(path3, Is.EqualTo(testPath)); 101 | } 102 | 103 | [Test] 104 | public void TestCombineMember() 105 | { 106 | ScriptPvfPath testPath = new ScriptPvfPath("abc/def/xyz.equ"); 107 | ScriptPvfPath path1 = new ScriptPvfPath("abc"); 108 | ScriptPvfPath path2 = new ScriptPvfPath("def/xyz.equ"); 109 | Assert.That(testPath, Is.EqualTo(ScriptPvfPath.Combine(path1, path2))); 110 | ScriptPvfPath empty = new ScriptPvfPath(@"\"); 111 | Assert.That(ScriptPvfPath.Combine(empty, empty), Is.EqualTo(empty)); 112 | Assert.That(ScriptPvfPath.Combine(path1, empty), Is.EqualTo(path1)); 113 | Assert.That(ScriptPvfPath.Combine(empty, path2), Is.EqualTo(path2)); 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /DFO.Common.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /DFO.Common/DFO.Common.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {F96DE472-94CE-46DC-89FE-049207CC9541} 8 | Library 9 | Properties 10 | DFO.Common 11 | DFO.Common 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | true 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | true 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | {9aba11f3-61ac-4b40-8432-91b3fe9ca351} 56 | DFO.Utilities 57 | 58 | 59 | 60 | 67 | -------------------------------------------------------------------------------- /DFO.Common/Images/AnimationFrame.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using DFO.Utilities; 6 | 7 | namespace DFO.Common.Images 8 | { 9 | public class AnimationFrame : IConstable 10 | { 11 | public ImageIdentifier Image { get; set; } 12 | public int PositionX { get; set; } 13 | public int PositionY { get; set; } 14 | 15 | private decimal m_imageRateX = 1.000000m; 16 | public decimal ImageRateX { get { return m_imageRateX; } set { m_imageRateX = value; } } 17 | 18 | private decimal m_imageRateY = 1.000000m; 19 | public decimal ImageRateY { get { return m_imageRateY; } set { m_imageRateY = value; } } 20 | 21 | private decimal m_imageRotate = 0m; 22 | public decimal ImageRotate { get { return m_imageRotate; } set { m_imageRotate = value; } } 23 | 24 | private int m_red = 255; 25 | public int Red { get { return m_red; } set { m_red = value; } } 26 | 27 | private int m_green = 255; 28 | public int Green { get { return m_green; } set { m_green = value; } } 29 | 30 | private int m_blue = 255; 31 | public int Blue { get { return m_blue; } set { m_blue = value; } } 32 | 33 | private int m_alpha = 255; 34 | public int Alpha { get { return m_alpha; } set { m_alpha = value; } } 35 | 36 | private bool m_interpolation = false; 37 | public bool Interpolation { get { return m_interpolation; } set { m_interpolation = value; } } 38 | 39 | private string m_graphicEffect = "NONE"; 40 | public string GraphicEffect { get { return m_graphicEffect; } set { m_graphicEffect = value; } } 41 | 42 | private int m_delayInMs; 43 | public int DelayInMs 44 | { 45 | get { return m_delayInMs; } 46 | set 47 | { 48 | if (value < 0) 49 | { 50 | throw new ArgumentOutOfRangeException("DelayInMs", string.Format("Delay in ms cannot be {0}, it must not be negative.", value)); 51 | } 52 | m_delayInMs = value; 53 | } 54 | } 55 | 56 | public AnimationFrame() 57 | { 58 | ; 59 | } 60 | 61 | /// 62 | /// Copy constructor 63 | /// 64 | /// 65 | public AnimationFrame(ConstAnimationFrame other) 66 | { 67 | this.Alpha = other.Alpha; 68 | this.Blue = other.Blue; 69 | this.DelayInMs = other.DelayInMs; 70 | this.GraphicEffect = other.GraphicEffect; 71 | this.Green = other.Green; 72 | this.Image = other.Image; 73 | this.PositionX = other.PositionX; 74 | this.PositionY = other.PositionY; 75 | this.ImageRateX = other.ImageRateX; 76 | this.ImageRateY = other.ImageRateY; 77 | this.ImageRotate = other.ImageRotate; 78 | this.Interpolation = other.Interpolation; 79 | this.Red = other.Red; 80 | } 81 | 82 | public ConstAnimationFrame AsConst() 83 | { 84 | return new ConstAnimationFrame(this); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /DFO.Common/Images/ConstAnimationFrame.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using DFO.Utilities; 6 | 7 | namespace DFO.Common.Images 8 | { 9 | public class ConstAnimationFrame 10 | { 11 | private AnimationFrame m_mutable; 12 | 13 | public ImageIdentifier Image { get { return m_mutable.Image; } } 14 | public int PositionX { get { return m_mutable.PositionX; } } 15 | public int PositionY { get { return m_mutable.PositionY; } } 16 | public decimal ImageRateX { get { return m_mutable.ImageRateX; } } 17 | public decimal ImageRateY { get { return m_mutable.ImageRateY; } } 18 | public decimal ImageRotate { get { return m_mutable.ImageRotate; } } 19 | public int Red { get { return m_mutable.Red; } } 20 | public int Green { get { return m_mutable.Green; } } 21 | public int Blue { get { return m_mutable.Blue; } } 22 | public int Alpha { get { return m_mutable.Alpha; } } 23 | public bool Interpolation { get { return m_mutable.Interpolation; } } 24 | public string GraphicEffect { get { return m_mutable.GraphicEffect; } } 25 | public int DelayInMs { get { return m_mutable.DelayInMs; } } 26 | // TODO: DamageType - don't know possible values at this time 27 | // TODO: DamageBox - don't know structure of it at this time 28 | // TODO: Find out what other settings are possible 29 | 30 | public ConstAnimationFrame(AnimationFrame mutable) 31 | { 32 | m_mutable = mutable; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /DFO.Common/Images/ConstRawAnimation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Collections.ObjectModel; 6 | 7 | namespace DFO.Common.Images 8 | { 9 | public class ConstRawAnimation 10 | { 11 | private RawAnimation m_mutable; 12 | 13 | public bool Loop { get { return m_mutable.Loop; } } 14 | public bool Shadow { get { return m_mutable.Shadow; } } 15 | public ReadOnlyCollection Frames { get { return new ReadOnlyCollection( m_mutable.Frames ); } } 16 | 17 | public ConstRawAnimation( RawAnimation mutable ) 18 | { 19 | m_mutable = mutable; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /DFO.Common/Images/FrameInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using DFO.Utilities; 6 | 7 | namespace DFO.Common.Images 8 | { 9 | public class FrameInfo 10 | { 11 | /// 12 | /// Gets the index of the frame that this frame links to or null if this frame is not a link. 13 | /// 14 | public int? LinkFrame { get; private set; } 15 | 16 | public bool IsCompressed { get; private set; } 17 | public int CompressedLength { get; private set; } 18 | public PixelDataFormat PixelFormat { get; private set; } 19 | public int Width { get; private set; } 20 | public int Height { get; private set; } 21 | public int LocationX { get; private set; } 22 | public int LocationY { get; private set; } 23 | public int MaxWidth { get; private set; } 24 | public int MaxHeight { get; private set; } 25 | 26 | public FrameInfo(int linkFrame) 27 | { 28 | LinkFrame = linkFrame; 29 | PixelFormat = PixelDataFormat.Link; 30 | } 31 | 32 | public FrameInfo(bool isCompressed, int compressedLength, PixelDataFormat pixelFormat, int width, int height, int locationX, int locationY, int maxWidth, 33 | int maxHeight) 34 | { 35 | IsCompressed = isCompressed; 36 | CompressedLength = compressedLength; 37 | PixelFormat = pixelFormat; 38 | Width = width; 39 | Height = height; 40 | LocationX = locationX; 41 | LocationY = locationY; 42 | MaxWidth = maxWidth; 43 | MaxHeight = maxHeight; 44 | } 45 | 46 | public int GetPixelDataLength() 47 | { 48 | if (PixelFormat == PixelDataFormat.Link) 49 | { 50 | return 0; 51 | } 52 | 53 | if (IsCompressed) 54 | { 55 | return CompressedLength; 56 | } 57 | else 58 | { 59 | return Width * Height * GetBytesPerPixel(); 60 | } 61 | } 62 | 63 | public static int GetBytesPerPixel(PixelDataFormat pixelFormat) 64 | { 65 | switch(pixelFormat) 66 | { 67 | case PixelDataFormat.EightEightEightEight: 68 | return 4; 69 | case PixelDataFormat.FourFourFourFour: 70 | return 2; 71 | case PixelDataFormat.OneFiveFiveFive: 72 | return 2; 73 | case PixelDataFormat.Link: 74 | return 0; 75 | default: 76 | throw new Exception("Invalid pixel format {0}.".F(pixelFormat)); 77 | } 78 | } 79 | 80 | public int GetBytesPerPixel() 81 | { 82 | return GetBytesPerPixel(PixelFormat); 83 | } 84 | 85 | public static void GetNormalizedCoordinates(IEnumerable frames, out int smallestX, out int largestX, out int smallestY, out int largestY) 86 | { 87 | smallestX = int.MaxValue; 88 | largestX = 0; 89 | smallestY = int.MaxValue; 90 | largestY = 0; 91 | 92 | foreach (FrameInfo frame in frames) 93 | { 94 | int startX = frame.LocationX; 95 | int endX = startX + frame.Width - 1; 96 | int startY = frame.LocationY; 97 | int endY = startY + frame.Height - 1; 98 | 99 | if (startX < smallestX) 100 | { 101 | smallestX = startX; 102 | } 103 | if (endX > largestX) 104 | { 105 | largestX = endX; 106 | } 107 | if (startY < smallestY) 108 | { 109 | smallestY = startY; 110 | } 111 | if (endY > largestY) 112 | { 113 | largestY = endY; 114 | } 115 | } 116 | } 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /DFO.Common/Images/IImageSource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DFO.Common.Images 8 | { 9 | public interface IImageSource : IDisposable 10 | { 11 | /// 12 | /// 13 | /// 14 | /// The Npk Path of the .img file, WITHOUT the leading sprite/ 15 | /// 16 | /// 17 | /// The img file does not exist in this .npk file 18 | /// or no frame with the given index exists in the img file. 19 | Image GetImage(NpkPath imgPath, int frameIndex); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /DFO.Common/Images/Image.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using DFO.Common.Images; 7 | 8 | namespace DFO.Common.Images 9 | { 10 | public class Image 11 | { 12 | /// 13 | /// In RGBA format, 1 byte each for R, G, B, A. 14 | /// 15 | public byte[] PixelData { get; private set; } 16 | public FrameInfo Attributes { get; private set; } 17 | 18 | public Image(byte[] pixelData, FrameInfo attributes) 19 | { 20 | PixelData = pixelData; 21 | Attributes = attributes; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /DFO.Common/Images/ImageIdentifier.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using DFO.Utilities; 7 | 8 | namespace DFO.Common.Images 9 | { 10 | public class ImageIdentifier 11 | { 12 | public NpkPath ImageFilePath { get; private set; } 13 | public int FrameIndex { get; private set; } 14 | 15 | public ImageIdentifier(NpkPath imageFilePath, int frameIndex) 16 | { 17 | ImageFilePath = imageFilePath; 18 | FrameIndex = frameIndex; 19 | } 20 | 21 | public override string ToString() 22 | { 23 | return "{0} {1}".F(ImageFilePath, FrameIndex); 24 | } 25 | 26 | // Don't make it public because this is doing a string comparison of the image file path, 27 | // not a true path comparison. This is only for use by tests. 28 | internal bool Equals(ImageIdentifier other) 29 | { 30 | if (other == null) 31 | { 32 | return false; 33 | } 34 | return this.FrameIndex == other.FrameIndex && this.ImageFilePath.Equals(other.ImageFilePath); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /DFO.Common/Images/PixelDataFormat.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DFO.Common.Images 8 | { 9 | // These are in little-endian order, so 1555 ARGB should have the bytes on disk and in memory as BGRA 10 | public enum PixelDataFormat 11 | { 12 | OneFiveFiveFive = 14, // 0x0E 13 | FourFourFourFour = 15, // 0x0F 14 | EightEightEightEight = 16, // 0x10 15 | Link = 17 // 0x11 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /DFO.Common/Images/RawAnimation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using DFO.Utilities; 6 | 7 | namespace DFO.Common.Images 8 | { 9 | public class RawAnimation : IConstable 10 | { 11 | private bool m_loop = false; 12 | public bool Loop { get { return m_loop; } set { m_loop = value; } } 13 | 14 | private bool m_shadow = false; 15 | public bool Shadow { get { return m_shadow; } set { m_shadow = value; } } 16 | 17 | private IList m_frames = new List(); 18 | public IList Frames { get { return m_frames; } set { m_frames = value; } } 19 | 20 | public RawAnimation() 21 | { 22 | ; 23 | } 24 | 25 | public ConstRawAnimation AsConst() 26 | { 27 | return new ConstRawAnimation( this ); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /DFO.Common/NpkPath.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using DFO.Utilities; 6 | 7 | namespace DFO.Common 8 | { 9 | /// 10 | /// Represents the path of an image or sound located in a .npk file. Example: Sprite/Interface/Emoticon/Against.img. 11 | /// Npk Paths are not case-sensitive and may use either slashes or backslashes as separators. 12 | /// An Npk Path should contain a leading "sprite/" or "sounds/". 13 | /// 14 | public class NpkPath : IEquatable 15 | { 16 | // Let ScriptPvfPath take care of the parsing so that code isn't duplicated. 17 | private ScriptPvfPath m_path; 18 | public string Path { get { return m_path.ToString(); } } 19 | 20 | /// 21 | /// 22 | /// 23 | /// 24 | /// is null. 25 | public NpkPath(string path) 26 | { 27 | m_path = new ScriptPvfPath(path); 28 | } 29 | 30 | // path assumed to not be null 31 | private NpkPath(ScriptPvfPath path) 32 | { 33 | m_path = path; 34 | } 35 | 36 | /// 37 | /// Gets the Npk Path of the directory containing the file or directory this path refers to. 38 | /// The parent directory of the root directory is considered the root directory. 39 | /// 40 | /// 41 | public NpkPath GetContainingDirectory() 42 | { 43 | return new NpkPath(m_path.GetContainingDirectory()); 44 | } 45 | 46 | /// 47 | /// Gets the file name portion of the path (the directory name if the path refers to a directory). 48 | /// The file name of the root directory is considered the empty string. 49 | /// 50 | /// 51 | public NpkPath GetFileName() 52 | { 53 | return new NpkPath(m_path.GetFileName()); 54 | } 55 | 56 | /// 57 | /// Gets a list containing the components of this Npk Path. For example, the components of 58 | /// sprite/character/gunner/effect/aerialdashattack.img are "sprite", "character", "gunner", "effect", and 59 | /// "aerialdashattack.img". The root directory has 0 components. 60 | /// 61 | /// 62 | public IList GetPathComponents() 63 | { 64 | IList pvfPathComponents = m_path.GetPathComponents(); 65 | List npkPathComponents = new List(pvfPathComponents.Count); 66 | foreach (ScriptPvfPath pvfPathComponent in pvfPathComponents) 67 | { 68 | npkPathComponents.Add(new NpkPath(pvfPathComponent)); 69 | } 70 | return npkPathComponents; 71 | } 72 | 73 | /// 74 | /// Gets the name of the .npk file that an image file with this npk path would normally be in. 75 | /// For example, sprite/interface/emoticon/against.img -> sprite_interface_emoticon.npk. 76 | /// There are plenty of exceptions to this. 77 | /// 78 | /// 79 | public string GetImageNpkName() 80 | { 81 | // Get the path components, add a new path component "sprite" at the beginning, leave out the 82 | // file name (the last path component), join the new components with underscores, and append .npk 83 | return GetNpkName("sprite"); 84 | } 85 | 86 | /// 87 | /// Gets the name of the .npk file that a sound file with this npk path would normally be in. 88 | /// There are plenty of exceptions to this. 89 | /// 90 | /// 91 | public string GetSoundNpkName() 92 | { 93 | return GetNpkName("sounds"); 94 | } 95 | 96 | private string GetNpkName(string prefix) 97 | { 98 | IList pathComponents = m_path.GetPathComponents(); 99 | StringBuilder npkBuilder = new StringBuilder(); 100 | npkBuilder.Append(prefix); 101 | for (int componentIndex = 0; componentIndex < pathComponents.Count - 1; componentIndex++) 102 | { 103 | // If prefix is already the first component, skip to the next component 104 | if (componentIndex == 0 && pathComponents[componentIndex].ToString().Equals(prefix, StringComparison.OrdinalIgnoreCase)) 105 | { 106 | continue; 107 | } 108 | 109 | npkBuilder.Append("_"); 110 | npkBuilder.Append(pathComponents[componentIndex].ToString()); 111 | } 112 | npkBuilder.Append(".npk"); 113 | return npkBuilder.ToString(); 114 | } 115 | 116 | public NpkPath StripPrefix() 117 | { 118 | IList pathComponents = GetPathComponents(); 119 | NpkPath pathWithoutPrefix = new NpkPath(""); 120 | for (int i = 1; i < pathComponents.Count; i++) 121 | { 122 | pathWithoutPrefix = NpkPath.Combine(pathWithoutPrefix, pathComponents[i]); 123 | } 124 | 125 | return pathWithoutPrefix; 126 | } 127 | 128 | /// 129 | /// Combines two Npk Paths together to form one path. If either path is the root directory, the 130 | /// other path is returned. 131 | /// 132 | /// The first path. 133 | /// The second path. 134 | /// The combined path. 135 | /// or 136 | /// is null. 137 | public static NpkPath Combine(NpkPath path1, NpkPath path2) 138 | { 139 | path1.ThrowIfNull("path1"); 140 | path2.ThrowIfNull("path2"); 141 | return new NpkPath(ScriptPvfPath.Combine(path1.m_path, path2.m_path)); 142 | } 143 | 144 | public static implicit operator string(NpkPath npkPath) 145 | { 146 | return npkPath.Path; 147 | } 148 | 149 | public static implicit operator NpkPath(string path) 150 | { 151 | if (path == null) 152 | { 153 | return null; 154 | } 155 | else 156 | { 157 | return new NpkPath(path); 158 | } 159 | } 160 | 161 | public override bool Equals(object obj) 162 | { 163 | return Equals(obj as NpkPath); 164 | } 165 | 166 | public bool Equals(NpkPath other) 167 | { 168 | if (ReferenceEquals(other, null)) 169 | { 170 | return false; 171 | } 172 | return m_path.Equals(other.m_path); 173 | } 174 | 175 | public bool Equals(string other) 176 | { 177 | if (ReferenceEquals(other, null)) 178 | { 179 | return false; 180 | } 181 | return Equals(new NpkPath(other)); 182 | } 183 | 184 | public static bool operator ==(NpkPath first, NpkPath second) 185 | { 186 | return first.Equals(second); 187 | } 188 | 189 | public static bool operator !=(NpkPath first, NpkPath second) 190 | { 191 | return !first.Equals(second); 192 | } 193 | 194 | public override string ToString() 195 | { 196 | return Path; 197 | } 198 | 199 | public override int GetHashCode() 200 | { 201 | return m_path.GetHashCode(); 202 | } 203 | } 204 | } 205 | -------------------------------------------------------------------------------- /DFO.Common/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DFO.Common")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DFO Toolbox")] 13 | [assembly: AssemblyCopyright("Copyright © LHCGreg 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("99f11715-8aae-4b14-ad22-bd34e2ac1ad8")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("0.3.0.0")] 36 | [assembly: AssemblyFileVersion("0.3.0.0")] 37 | -------------------------------------------------------------------------------- /DFO.Images/DFO.Images.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {44912ED2-024B-4EBF-B02F-910142C81E75} 8 | Library 9 | Properties 10 | DFO.Images 11 | DFO.Images 12 | v4.5 13 | 512 14 | ae126a1f 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | true 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | true 34 | 35 | 36 | 37 | False 38 | ..\packages\GraphicsMagick.NET-Q8-AnyCPU.1.3.21.1\lib\net40-client\GraphicsMagick.NET-AnyCPU.dll 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | {f96de472-94ce-46dc-89fe-049207cc9541} 57 | DFO.Common 58 | 59 | 60 | 61 | 62 | 63 | 64 | 71 | -------------------------------------------------------------------------------- /DFO.Images/Export.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using DFO.Common; 8 | using DFO.Common.Images; 9 | using GraphicsMagick; 10 | 11 | namespace DFO.Images 12 | { 13 | public static class Export 14 | { 15 | /// 16 | /// Exports a frame as a PNG file. 17 | /// 18 | /// Source of images. Normally an NPK reader, but could be also be a source that reads from 19 | /// an extraction or a mock source. 20 | /// 21 | /// 22 | /// stream to write the PNG to 23 | /// Image with the given path and frame index does not exist. 24 | public static void ToPng(IImageSource imageSource, NpkPath imgPath, int frameIndex, Stream outputStream) 25 | { 26 | Image image = imageSource.GetImage(imgPath, frameIndex); 27 | 28 | MagickReadSettings pixelDataSettings = new MagickReadSettings() 29 | { 30 | ColorSpace = ColorSpace.RGB, 31 | Width = image.Attributes.Width, 32 | Height = image.Attributes.Height, 33 | PixelStorage = new PixelStorageSettings(StorageType.Char, "RGBA") 34 | }; 35 | 36 | using (MagickImage magickImage = new MagickImage(image.PixelData, pixelDataSettings)) 37 | { 38 | magickImage.Write(outputStream, MagickFormat.Png); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /DFO.Images/GifMaker.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using DFO.Common; 7 | using DFO.Common.Images; 8 | using GraphicsMagick; 9 | 10 | namespace DFO.Images 11 | { 12 | public class GifMaker : IDisposable 13 | { 14 | private IImageSource m_imageSource; 15 | private bool m_disposeImageSource; 16 | 17 | /// 18 | /// 19 | /// 20 | /// Source of images. Normally an NPK reader, but could be also be a source that reads from 21 | /// an extraction or a mock source. 22 | /// If true, Dispose() the image source when this object is disposed. 23 | public GifMaker(IImageSource imageSource, bool disposeImageSource) 24 | { 25 | m_imageSource = imageSource; 26 | m_disposeImageSource = disposeImageSource; 27 | } 28 | 29 | public void Dispose() 30 | { 31 | if (m_disposeImageSource) 32 | { 33 | m_imageSource.Dispose(); 34 | } 35 | } 36 | 37 | /// 38 | /// Creates an animated GIF and writes it to . 39 | /// 40 | /// 41 | /// 42 | public void Create(ConstRawAnimation animation, Stream outputStream) 43 | { 44 | List rawFrames = new List(); 45 | 46 | // Load each image in the animation. 47 | foreach (ConstAnimationFrame frame in animation.Frames) 48 | { 49 | NpkPath frameImagePath = frame.Image.ImageFilePath; 50 | DFO.Common.Images.Image rawFrame = m_imageSource.GetImage(frameImagePath, frame.Image.FrameIndex); 51 | rawFrames.Add(rawFrame); 52 | } 53 | 54 | int smallestX; 55 | int largestX; 56 | int smallestY; 57 | int largestY; 58 | 59 | // Frames can have different start positions and widths/heights. Normalize the images to a common coordinate system. 60 | FrameInfo.GetNormalizedCoordinates(rawFrames.Select(image => image.Attributes), out smallestX, out largestX, out smallestY, out largestY); 61 | 62 | int normalizedWidth = largestX - smallestX + 1; 63 | int normalizedHeight = largestY - smallestY + 1; 64 | 65 | List renderedFrames = new List(); 66 | 67 | try 68 | { 69 | // Composite each frame on top of a canvas of normalized width and height. 70 | for (int frameIndex = 0; frameIndex < animation.Frames.Count; frameIndex++) 71 | { 72 | Image rawFrameImage = rawFrames[frameIndex]; 73 | ConstAnimationFrame frameAnimationInfo = animation.Frames[frameIndex]; 74 | 75 | MagickImage renderedFrame = RenderFrame(rawFrameImage, frameAnimationInfo, smallestX, largestX, smallestY, largestY, normalizedWidth, normalizedHeight); 76 | renderedFrames.Add(renderedFrame); 77 | } 78 | 79 | // Make the GIF from the frames and write it out to the stream. 80 | using (MagickImageCollection frameCollection = new GraphicsMagick.MagickImageCollection(renderedFrames)) 81 | { 82 | frameCollection.Write(outputStream, MagickFormat.Gif); 83 | } 84 | } 85 | finally 86 | { 87 | renderedFrames.ForEach(f => f.Dispose()); 88 | } 89 | } 90 | 91 | private MagickImage RenderFrame(Image rawFrameImage, ConstAnimationFrame frameAnimationInfo, int smallestX, int largestX, int smallestY, int largestY, int normalizedWidth, int normalizedHeight) 92 | { 93 | MagickImage renderedFrame = new MagickImage(new MagickColor(0, 0, 0, 0), normalizedWidth, normalizedHeight); 94 | 95 | int normalizedFrameX = rawFrameImage.Attributes.LocationX - smallestX; 96 | int normalizedFrameY = rawFrameImage.Attributes.LocationY - smallestY; 97 | 98 | if (rawFrameImage.PixelData.Length > 0) 99 | { 100 | MagickReadSettings pixelDataSettings = new MagickReadSettings() 101 | { 102 | ColorSpace = ColorSpace.RGB, 103 | Width = rawFrameImage.Attributes.Width, 104 | Height = rawFrameImage.Attributes.Height, 105 | PixelStorage = new PixelStorageSettings(StorageType.Char, "RGBA") 106 | }; 107 | 108 | using (MagickImage rawFrameMagickImage = new MagickImage(rawFrameImage.PixelData, pixelDataSettings)) 109 | { 110 | rawFrameMagickImage.Format = MagickFormat.Gif; 111 | rawFrameMagickImage.MatteColor = new MagickColor(0, 0, 0, 0); 112 | renderedFrame.Composite(rawFrameMagickImage, normalizedFrameX, normalizedFrameY, CompositeOperator.Over); 113 | } 114 | } 115 | 116 | renderedFrame.Format = MagickFormat.Gif; 117 | renderedFrame.AnimationDelay = frameAnimationInfo.DelayInMs / 10; 118 | renderedFrame.GifDisposeMethod = GifDisposeMethod.Background; 119 | renderedFrame.AnimationIterations = 0; 120 | renderedFrame.MatteColor = new MagickColor(0, 0, 0, 0); 121 | 122 | return renderedFrame; 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /DFO.Images/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DFO.Images")] 9 | [assembly: AssemblyDescription("Library for exporting DFO images as various formats")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DFO Toolbox")] 13 | [assembly: AssemblyCopyright("Copyright © LHCGreg 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("1951d080-8ef9-4794-9046-b3c53569209a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("0.3.0.0")] 36 | [assembly: AssemblyFileVersion("0.3.0.0")] 37 | -------------------------------------------------------------------------------- /DFO.Images/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /DFO.Npk.IntegrationTests/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /DFO.Npk.IntegrationTests/Config.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace DFO.Npk.IntegrationTests 9 | { 10 | class Config 11 | { 12 | public string ImageNpkDir { get; private set; } 13 | 14 | public Config() 15 | { 16 | ImageNpkDir = ConfigurationManager.AppSettings["ImageNpkDir"]; 17 | if (ImageNpkDir == null) 18 | { 19 | throw new Exception("ImageNpkDir appsetting not set."); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /DFO.Npk.IntegrationTests/DFO.Npk.IntegrationTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {24DD7BAA-7B3A-420E-9D99-B0ADD7F41C5E} 8 | Library 9 | Properties 10 | DFO.Npk.IntegrationTests 11 | DFO.Npk.IntegrationTests 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | true 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | true 33 | 34 | 35 | 36 | False 37 | ..\packages\NUnit.2.6.4\lib\nunit.framework.dll 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | {f96de472-94ce-46dc-89fe-049207cc9541} 52 | DFO.Common 53 | 54 | 55 | {04c832f4-8f9d-457a-99fe-cc33eaa98bfe} 56 | DFO.Npk 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 74 | -------------------------------------------------------------------------------- /DFO.Npk.IntegrationTests/NpkReaderTestFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using DFO.Common; 8 | using DFO.Common.Images; 9 | using NUnit.Framework; 10 | 11 | namespace DFO.Npk.IntegrationTests 12 | { 13 | [TestFixture] 14 | public class NpkReaderTestFixture 15 | { 16 | [Test] 17 | public void ReadAllImages() 18 | { 19 | Config config = new Config(); 20 | List extraErrors = new List(); 21 | foreach (string path in Directory.GetFiles(config.ImageNpkDir, "*.NPK")) 22 | { 23 | using (NpkReader npk = new NpkReader(path, extraErrorHandler: (sender, args) => { extraErrors.Add(args.Message); Console.WriteLine(args.Message); })) 24 | { 25 | npk.PreLoadAllSpriteFrameMetadata(); 26 | 27 | foreach (NpkPath imgPath in npk.Frames.Keys) 28 | { 29 | IReadOnlyList imgFrames = npk.Frames[imgPath]; 30 | for (int frameIndex = 0; frameIndex < imgFrames.Count; frameIndex++) 31 | { 32 | npk.GetImage(imgPath, frameIndex); 33 | } 34 | } 35 | 36 | if (extraErrors.Count > 0) 37 | { 38 | throw new Exception("Errors detected. Check console output for details."); 39 | } 40 | } 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /DFO.Npk.IntegrationTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DFO.Npk.IntegrationTests")] 9 | [assembly: AssemblyDescription("Integration tests for DFO.Npk")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DFO Toolbox")] 13 | [assembly: AssemblyCopyright("Copyright © LHCGreg 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("cf379e8f-6db6-4184-9cf6-c715b922e4bb")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /DFO.Npk.IntegrationTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /DFO.Npk.IntegrationTests/setup.txt: -------------------------------------------------------------------------------- 1 | Setup required to run these tests: 2 | 3 | A full set of ImagePacks2 NPK files at (by default) C:\Neople\DFO\ImagePacks2. The path can be changed in the app.config. -------------------------------------------------------------------------------- /DFO.Npk/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /DFO.Npk/DFO.Npk.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {04C832F4-8F9D-457A-99FE-CC33EAA98BFE} 8 | Library 9 | Properties 10 | DFO.Npk 11 | DFO.Npk 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | true 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | true 35 | 36 | 37 | 38 | 39 | 40 | 41 | ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll 42 | 43 | 44 | ..\packages\JonSkeet.MiscUtil.0.1\lib\net35-Client\MiscUtil.dll 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | {f96de472-94ce-46dc-89fe-049207cc9541} 70 | DFO.Common 71 | 72 | 73 | {9aba11f3-61ac-4b40-8432-91b3fe9ca351} 74 | DFO.Utilities 75 | 76 | 77 | 78 | 85 | -------------------------------------------------------------------------------- /DFO.Npk/IReadableFrame.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DFO.Npk 8 | { 9 | public interface IReadableFrame 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /DFO.Npk/NpkByteRange.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace DFO.Npk 7 | { 8 | /// 9 | /// Represents a region of an .npk file. 10 | /// 11 | internal struct NpkByteRange : IEquatable 12 | { 13 | public int FileOffset { get; private set; } 14 | public int Size { get; private set; } 15 | 16 | public NpkByteRange(int fileOffset, int size) 17 | : this() 18 | { 19 | FileOffset = fileOffset; 20 | Size = size; 21 | } 22 | 23 | public override bool Equals(object obj) 24 | { 25 | if (obj is NpkByteRange) 26 | return Equals((NpkByteRange)obj); 27 | else 28 | return false; 29 | } 30 | 31 | public bool Equals(NpkByteRange other) 32 | { 33 | return this.FileOffset == other.FileOffset && this.Size == other.Size; 34 | } 35 | 36 | public override int GetHashCode() 37 | { 38 | unchecked 39 | { 40 | int hash = 23; 41 | hash = hash * 31 + FileOffset; 42 | hash = hash * 31 + Size; 43 | return hash; 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /DFO.Npk/NpkException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.Serialization; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace DFO.Npk 9 | { 10 | /// 11 | /// Indicates a malformed .npk file. 12 | /// 13 | [Serializable] 14 | public class NpkException : Exception 15 | { 16 | public NpkException() { } 17 | public NpkException(string message) : base(message) { } 18 | public NpkException(string message, Exception inner) : base(message, inner) { } 19 | protected NpkException( 20 | SerializationInfo info, 21 | StreamingContext context) 22 | : base(info, context) { } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /DFO.Npk/NpkFileTableEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using DFO.Common; 7 | 8 | namespace DFO.Npk 9 | { 10 | internal struct NpkFileTableEntry 11 | { 12 | private NpkPath _name; 13 | private NpkByteRange _location; 14 | 15 | public NpkPath Name { get { return _name; } } 16 | public NpkByteRange Location { get { return _location; } } 17 | 18 | public NpkFileTableEntry(NpkPath name, NpkByteRange location) 19 | { 20 | _name = name; 21 | _location = location; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /DFO.Npk/NpkReader.LazyFramesReadOnlyDictionary.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using DFO.Common; 9 | using DFO.Common.Images; 10 | using DFO.Utilities; 11 | 12 | namespace DFO.Npk 13 | { 14 | public partial class NpkReader 15 | { 16 | /// 17 | /// Lazily loads frame metadata as needed, presenting a convenient interface. 18 | /// 19 | internal class LazyFramesReadOnlyDictionary : IReadOnlyDictionary> 20 | { 21 | private NpkReader m_npk; 22 | 23 | public LazyFramesReadOnlyDictionary(NpkReader npk) 24 | { 25 | npk.ThrowIfNull("npk"); 26 | m_npk = npk; 27 | } 28 | 29 | public bool ContainsKey(NpkPath key) 30 | { 31 | return m_npk.Images.ContainsKey(key); 32 | } 33 | 34 | public IEnumerable Keys 35 | { 36 | get { return m_npk.Images.Keys; } 37 | } 38 | 39 | public bool TryGetValue(NpkPath key, out IReadOnlyList value) 40 | { 41 | if (m_npk.Images.ContainsKey(key)) 42 | { 43 | m_npk.PreLoadSpriteMetadata(key); 44 | value = m_npk.m_frames[key]; 45 | return true; 46 | } 47 | else 48 | { 49 | value = null; 50 | return false; 51 | } 52 | } 53 | 54 | // The debugger does not seem to honor these...so frame metadata will get preloaded if you are debugging 55 | // and the debugger decides to evaluate this property 56 | [DebuggerBrowsable(DebuggerBrowsableState.Never)] 57 | [DebuggerHidden] 58 | public IEnumerable> Values 59 | { 60 | get 61 | { 62 | m_npk.PreLoadAllSpriteFrameMetadata(); 63 | return m_npk.m_frames.Values; 64 | } 65 | } 66 | 67 | public IReadOnlyList this[NpkPath key] 68 | { 69 | get 70 | { 71 | try 72 | { 73 | m_npk.PreLoadSpriteMetadata(key); 74 | } 75 | catch (FileNotFoundException ex) 76 | { 77 | throw new KeyNotFoundException(ex.Message, ex); 78 | } 79 | 80 | return m_npk.m_frames[key]; 81 | } 82 | } 83 | 84 | public int Count { get { return m_npk.Images.Count; } } 85 | 86 | public IEnumerator>> GetEnumerator() 87 | { 88 | foreach (NpkPath imgPath in m_npk.Images.Keys) 89 | { 90 | m_npk.PreLoadSpriteMetadata(imgPath); 91 | yield return new KeyValuePair>(imgPath, m_npk.m_frames[imgPath]); 92 | } 93 | } 94 | 95 | System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 96 | { 97 | return GetEnumerator(); 98 | } 99 | } 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /DFO.Npk/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DFO.Npk")] 9 | [assembly: AssemblyDescription("Library for reading DFO's .NPK files")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DFO Toolbox")] 13 | [assembly: AssemblyCopyright("Copyright © LHCGreg 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("fba957d2-0701-434a-bd56-b711983c7d2e")] 24 | 25 | [assembly: InternalsVisibleTo("DFO.Npk.IntegrationTests")] 26 | 27 | [assembly: AssemblyVersion("0.3.0.0")] 28 | [assembly: AssemblyFileVersion("0.3.0.0")] 29 | -------------------------------------------------------------------------------- /DFO.Npk/SoundInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace DFO.Npk 7 | { 8 | // Nothing for this class to do, maybe in the future but probably not 9 | public class SoundInfo 10 | { 11 | internal SoundInfo() 12 | { 13 | ; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /DFO.Npk/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /DFO.Sandbox/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /DFO.Sandbox/DFO.Sandbox.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {E070D4F5-863E-4911-AC42-8F9B827F8C20} 8 | Exe 9 | Properties 10 | DFO.Sandbox 11 | DFO.Sandbox 12 | v4.5 13 | 512 14 | c8a8dc79 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | true 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | true 36 | 37 | 38 | 39 | False 40 | ..\packages\GraphicsMagick.NET-Q8-AnyCPU.1.3.21.1\lib\net40-client\GraphicsMagick.NET-AnyCPU.dll 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | {f96de472-94ce-46dc-89fe-049207cc9541} 63 | DFO.Common 64 | 65 | 66 | {44912ed2-024b-4ebf-b02f-910142c81e75} 67 | DFO.Images 68 | 69 | 70 | {9aba11f3-61ac-4b40-8432-91b3fe9ca351} 71 | DFO.Utilities 72 | 73 | 74 | {04c832f4-8f9d-457a-99fe-cc33eaa98bfe} 75 | DFO.Npk 76 | 77 | 78 | 79 | 86 | -------------------------------------------------------------------------------- /DFO.Sandbox/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Drawing; 4 | using System.Drawing.Imaging; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Media.Imaging; 10 | using DFO.Common; 11 | using DFO.Common.Images; 12 | using DFO.Images; 13 | using DFO.Npk; 14 | 15 | namespace DFO.Sandbox 16 | { 17 | class Program 18 | { 19 | static void Main(string[] args) 20 | { 21 | using (NpkReader npk = new NpkReader(@"C:\Neople\DFO\ImagePacks2\sprite_character_fighter_equipment_avatar_cap.NPK")) 22 | { 23 | npk.PreLoadAllSpriteFrameMetadata(); 24 | List imgs = npk.Frames.Where(kvp => kvp.Value.Any(f => f.CompressedLength == 84)).Select(kvp => kvp.Key).ToList(); 25 | foreach (NpkPath img in imgs) 26 | { 27 | IReadOnlyList frames = npk.Frames[img]; 28 | for (int i = 0; i < frames.Count; i++) 29 | { 30 | if (frames[i].CompressedLength == 84 && !frames[i].IsCompressed) 31 | { 32 | Console.WriteLine(string.Format("{0} {1}", img, i)); 33 | } 34 | } 35 | } 36 | } 37 | 38 | Environment.Exit(0); 39 | 40 | foreach (string path in Directory.GetFiles(@"C:\Neople\DFO\ImagePacks2", "*.NPK")) 41 | { 42 | Console.WriteLine(path); 43 | using (NpkReader npk = new NpkReader(path)) 44 | { 45 | npk.PreLoadAllSpriteFrameMetadata(); 46 | foreach (NpkPath npkPath in npk.Frames.Keys) 47 | { 48 | var x = npk.Frames[npkPath]; 49 | for(int i = 0; i < x.Count; i++) 50 | { 51 | FrameInfo frame = x[i]; 52 | if (!frame.IsCompressed && frame.LinkFrame == null) 53 | { 54 | string pixelFormatString = frame.PixelFormat.ToString(); 55 | int actualLength = frame.Width * frame.Height * 2; 56 | if (frame.PixelFormat == PixelDataFormat.EightEightEightEight) 57 | { 58 | actualLength *= 2; 59 | } 60 | if (frame.CompressedLength != actualLength) 61 | { 62 | Console.WriteLine("Pixel Format: {0,22}, Compressed Length: {1,9}, Actual Length: {2,9} {3} {4}", pixelFormatString, frame.CompressedLength, actualLength, npkPath, i); 63 | } 64 | } 65 | } 66 | } 67 | } 68 | } 69 | 70 | Environment.Exit(0); 71 | 72 | using (NpkReader npkReader = new NpkReader(@"C:\Neople\DFO\ImagePacks2\sprite_monster_impossible_bakal.NPK")) 73 | using (NpkReader coolReader = new NpkReader(@"C:\Neople\DFO\ImagePacks2\sprite_character_swordman_effect_sayaex.NPK")) 74 | { 75 | DFO.Common.Images.Image image = npkReader.GetImage("monster/impossible_bakal/ashcore.img", 0); 76 | //Image image2 = npkReader.GetImage("worldmap/act1/elvengard.img", 1); 77 | using (Bitmap bitmap = new Bitmap(image.Attributes.Width, image.Attributes.Height)) 78 | { 79 | BitmapData raw = bitmap.LockBits(new Rectangle(0, 0, image.Attributes.Width, image.Attributes.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); 80 | unsafe 81 | { 82 | byte* ptr = (byte*)raw.Scan0; 83 | // RGBA -> BGRA (pixels in the bitmap have endianness) 84 | int width = image.Attributes.Width; 85 | int height = image.Attributes.Height; 86 | int stride = raw.Stride; 87 | for (int x = 0; x < width; x++) 88 | { 89 | for (int y = 0; y < height; y++) 90 | { 91 | ptr[y * stride + x * 4 + 0] = image.PixelData[y * width * 4 + x * 4 + 2]; 92 | ptr[y * stride + x * 4 + 1] = image.PixelData[y * width * 4 + x * 4 + 1]; 93 | ptr[y * stride + x * 4 + 2] = image.PixelData[y * width * 4 + x * 4 + 0]; 94 | ptr[y * stride + x * 4 + 3] = image.PixelData[y * width * 4 + x * 4 + 3]; 95 | } 96 | } 97 | } 98 | bitmap.UnlockBits(raw); 99 | bitmap.Save(@"output.png", System.Drawing.Imaging.ImageFormat.Png); 100 | 101 | 102 | RawAnimation animationData = new RawAnimation(); 103 | animationData.Loop = true; 104 | animationData.Frames = new List() 105 | { 106 | new AnimationFrame() { DelayInMs = 1000, Image = new ImageIdentifier("worldmap/act1/elvengard.img", 0) }.AsConst(), 107 | new AnimationFrame() { DelayInMs = 1000, Image = new ImageIdentifier("worldmap/act1/elvengard.img", 1) }.AsConst() 108 | }; 109 | 110 | RawAnimation cool = new RawAnimation(); 111 | cool.Loop = true; 112 | cool.Frames = new List() 113 | { 114 | new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 0) }.AsConst(), 115 | new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 1) }.AsConst(), 116 | new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 2) }.AsConst(), 117 | new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 3) }.AsConst(), 118 | new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 4) }.AsConst(), 119 | new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 5) }.AsConst(), 120 | new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 6) }.AsConst(), 121 | new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 7) }.AsConst(), 122 | new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 8) }.AsConst(), 123 | new AnimationFrame() { DelayInMs = 100, Image = new ImageIdentifier("character/swordman/effect/sayaex/wingdodge.img", 9) }.AsConst(), 124 | }; 125 | 126 | using (GifMaker giffer = new GifMaker(npkReader, disposeImageSource: false)) 127 | using (GifMaker coolGiffer = new GifMaker(coolReader, disposeImageSource: false)) 128 | using (FileStream gifOutputStream = new FileStream("output.gif", FileMode.Create, FileAccess.ReadWrite, FileShare.None)) 129 | using (FileStream coolGifOutputStream = new FileStream("cool.gif", FileMode.Create, FileAccess.ReadWrite, FileShare.None)) 130 | { 131 | giffer.Create(animationData.AsConst(), gifOutputStream); 132 | coolGiffer.Create(cool.AsConst(), coolGifOutputStream); 133 | } 134 | } 135 | 136 | Console.WriteLine("Success!"); 137 | } 138 | } 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /DFO.Sandbox/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DFO.Sandbox")] 9 | [assembly: AssemblyDescription("Sandbox project for playing with DFO code")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DFO Toolbox")] 13 | [assembly: AssemblyCopyright("Copyright © LHCGreg 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("bb04f8ab-71c5-4f85-8bf9-8612c231cf90")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /DFO.Sandbox/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /DFO.Utilities/DFO.Utilities.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {9ABA11F3-61AC-4B40-8432-91B3FE9CA351} 8 | Library 9 | Properties 10 | DFO.Utilities 11 | DFO.Utilities 12 | v4.5 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | true 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | true 33 | 34 | 35 | 36 | ..\packages\JonSkeet.MiscUtil.0.1\lib\net35-Client\MiscUtil.dll 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 59 | -------------------------------------------------------------------------------- /DFO.Utilities/IConstable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace DFO.Utilities 7 | { 8 | public interface IConstable 9 | { 10 | TConst AsConst(); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /DFO.Utilities/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DFO.Utilities")] 9 | [assembly: AssemblyDescription("Non-DFO related utility library")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DFO Toolbox")] 13 | [assembly: AssemblyCopyright("Copyright © LHCGreg 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f6b093e2-29ec-46ff-acfc-cb782d76d076")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("0.3.0.0")] 36 | [assembly: AssemblyFileVersion("0.3.0.0")] 37 | -------------------------------------------------------------------------------- /DFO.Utilities/Utils.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | 7 | namespace DFO.Utilities 8 | { 9 | /// 10 | /// Static class containing utility methods. 11 | /// 12 | public static class Utils 13 | { 14 | /// 15 | /// Checks to make sure does not contain any characters in 16 | /// System.IO.Path.GetInvalidPathChars(). A null path is considered invalid. 17 | /// 18 | /// 19 | /// 20 | public static bool PathIsValid(string path) 21 | { 22 | if (path == null) 23 | { 24 | return false; 25 | } 26 | char[] invalidChars = Path.GetInvalidPathChars(); 27 | if (path.IndexOfAny(invalidChars) != -1) 28 | { 29 | return false; 30 | } 31 | else 32 | { 33 | return true; 34 | } 35 | } 36 | 37 | /// 38 | /// Converts a little-endian 32-bit signed integer to a native 32-bit signed integer. 39 | /// 40 | /// A buffer containing the 4 bytes to be converted. 41 | /// The index in the buffer that the 4 bytes starts at. 42 | /// The native signed integer representation of the little-endian signed integer. 43 | /// is null. 44 | /// is null. 45 | /// is less than zero 46 | /// or greater than the length of minus 4. 47 | /// is less than zero 48 | /// or greater than the length of minus 4. 49 | public static int LeToNativeInt32(byte[] buffer, int offset) 50 | { 51 | if (BitConverter.IsLittleEndian) 52 | { 53 | return BitConverter.ToInt32(buffer, offset); 54 | } 55 | else 56 | { 57 | int ret = 0; 58 | for (int i = 3; i >= 0; i--) 59 | { 60 | ret = unchecked((ret << 8) | buffer[offset + i]); 61 | } 62 | return ret; 63 | } 64 | } 65 | 66 | /// 67 | /// Converts a little-endian 32-bit unsigned integer to a native 32-bit unsigned integer. 68 | /// 69 | /// A buffer containing the 4 bytes to be converted. 70 | /// The index in the buffer that the 4 bytes starts at. 71 | /// The native unsigned integer representation of the little-endian unsigned integer. 72 | /// is null. 73 | /// is null. 74 | /// is less than zero 75 | /// or greater than the length of minus 4. 76 | /// is less than zero 77 | /// or greater than the length of minus 4. 78 | public static uint LeToNativeUInt32(byte[] buffer, int offset) 79 | { 80 | if (BitConverter.IsLittleEndian) 81 | { 82 | return BitConverter.ToUInt32(buffer, offset); 83 | } 84 | else 85 | { 86 | uint ret = 0; 87 | for (int i = 3; i >= 0; i--) 88 | { 89 | ret = unchecked((ret << 8) | buffer[offset + i]); 90 | } 91 | return ret; 92 | } 93 | } 94 | 95 | /// 96 | /// Converts a little-endian 16-bit signed integer to a native 16-bit signed integer. 97 | /// 98 | /// A buffer containing the 2 bytes to be converted. 99 | /// The index in the buffer that the 2 bytes starts at. 100 | /// The native signed integer representation of the little-endian signed integer. 101 | /// is null. 102 | /// is null. 103 | /// is less than zero 104 | /// or greater than the length of minus 2. 105 | /// is less than zero 106 | /// or greater than the length of minus 2. 107 | public static short LeToNativeInt16(byte[] buffer, int offset) 108 | { 109 | if (BitConverter.IsLittleEndian) 110 | { 111 | return BitConverter.ToInt16(buffer, offset); 112 | } 113 | else 114 | { 115 | short ret = 0; 116 | for (int i = 1; i >= 0; i--) 117 | { 118 | ret = unchecked((short)((ret << 8) | buffer[offset + i])); 119 | } 120 | return ret; 121 | } 122 | } 123 | 124 | /// 125 | /// Converts a little-endian 16-bit unsigned integer to a native 16-bit unsigned integer. 126 | /// 127 | /// A buffer containing the 2 bytes to be converted. 128 | /// The index in the buffer that the 2 bytes starts at. 129 | /// The native unsigned integer representation of the little-endian unsigned integer. 130 | /// is null. 131 | /// is null. 132 | /// is less than zero 133 | /// or greater than the length of minus 2. 134 | /// is less than zero 135 | /// or greater than the length of minus 2. 136 | public static ushort LeToNativeUInt16(byte[] buffer, int offset) 137 | { 138 | if (BitConverter.IsLittleEndian) 139 | { 140 | return BitConverter.ToUInt16(buffer, offset); 141 | } 142 | else 143 | { 144 | ushort ret = 0; 145 | for (int i = 1; i >= 0; i--) 146 | { 147 | ret = unchecked((ushort)((ret << 8) | buffer[offset + i])); 148 | } 149 | return ret; 150 | } 151 | } 152 | 153 | /// 154 | /// Returns ex.Message: innerex1.Message: innerex2.Message, etc 155 | /// 156 | /// 157 | /// 158 | public static string GetExceptionMessageWithInnerExceptions(Exception ex) 159 | { 160 | StringBuilder message = new StringBuilder(ex.Message); 161 | 162 | Exception innerEx = ex.InnerException; 163 | while (innerEx != null) 164 | { 165 | message.Append(": ").Append(innerEx.Message); 166 | innerEx = innerEx.InnerException; 167 | } 168 | 169 | return message.ToString(); 170 | } 171 | } 172 | } 173 | -------------------------------------------------------------------------------- /DFO.Utilities/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /DFOToolBox.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DFO.Npk", "DFO.Npk\DFO.Npk.csproj", "{04C832F4-8F9D-457A-99FE-CC33EAA98BFE}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DFO.Sandbox", "DFO.Sandbox\DFO.Sandbox.csproj", "{E070D4F5-863E-4911-AC42-8F9B827F8C20}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DFO.Common", "DFO.Common\DFO.Common.csproj", "{F96DE472-94CE-46DC-89FE-049207CC9541}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DFO.Utilities", "DFO.Utilities\DFO.Utilities.csproj", "{9ABA11F3-61AC-4B40-8432-91B3FE9CA351}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DFO.Images", "DFO.Images\DFO.Images.csproj", "{44912ED2-024B-4EBF-B02F-910142C81E75}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "npk2gif", "npk2gif\npk2gif.csproj", "{D4F67769-4AE4-46CA-8442-D463DE903C21}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DFO.Common.Tests", "DFO.Common.Tests\DFO.Common.Tests.csproj", "{016B332A-BEF3-496F-A896-3C5F2BC41238}" 19 | EndProject 20 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DFOToolbox", "DFOToolbox\DFOToolbox.csproj", "{F745AB63-3DCF-48E3-AD87-93FE67012F72}" 21 | EndProject 22 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DFO.Npk.IntegrationTests", "DFO.Npk.IntegrationTests\DFO.Npk.IntegrationTests.csproj", "{24DD7BAA-7B3A-420E-9D99-B0ADD7F41C5E}" 23 | EndProject 24 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "npkdiff", "npkdiff\npkdiff.csproj", "{C58E88D3-C68E-485B-9F37-92634216C182}" 25 | EndProject 26 | Global 27 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 28 | Debug|Any CPU = Debug|Any CPU 29 | Release|Any CPU = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 32 | {04C832F4-8F9D-457A-99FE-CC33EAA98BFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {04C832F4-8F9D-457A-99FE-CC33EAA98BFE}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {04C832F4-8F9D-457A-99FE-CC33EAA98BFE}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {04C832F4-8F9D-457A-99FE-CC33EAA98BFE}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {E070D4F5-863E-4911-AC42-8F9B827F8C20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {E070D4F5-863E-4911-AC42-8F9B827F8C20}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {E070D4F5-863E-4911-AC42-8F9B827F8C20}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {E070D4F5-863E-4911-AC42-8F9B827F8C20}.Release|Any CPU.Build.0 = Release|Any CPU 40 | {F96DE472-94CE-46DC-89FE-049207CC9541}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {F96DE472-94CE-46DC-89FE-049207CC9541}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {F96DE472-94CE-46DC-89FE-049207CC9541}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {F96DE472-94CE-46DC-89FE-049207CC9541}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {9ABA11F3-61AC-4B40-8432-91B3FE9CA351}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {9ABA11F3-61AC-4B40-8432-91B3FE9CA351}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {9ABA11F3-61AC-4B40-8432-91B3FE9CA351}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {9ABA11F3-61AC-4B40-8432-91B3FE9CA351}.Release|Any CPU.Build.0 = Release|Any CPU 48 | {44912ED2-024B-4EBF-B02F-910142C81E75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {44912ED2-024B-4EBF-B02F-910142C81E75}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {44912ED2-024B-4EBF-B02F-910142C81E75}.Release|Any CPU.ActiveCfg = Release|Any CPU 51 | {44912ED2-024B-4EBF-B02F-910142C81E75}.Release|Any CPU.Build.0 = Release|Any CPU 52 | {D4F67769-4AE4-46CA-8442-D463DE903C21}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 53 | {D4F67769-4AE4-46CA-8442-D463DE903C21}.Debug|Any CPU.Build.0 = Debug|Any CPU 54 | {D4F67769-4AE4-46CA-8442-D463DE903C21}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {D4F67769-4AE4-46CA-8442-D463DE903C21}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {016B332A-BEF3-496F-A896-3C5F2BC41238}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 57 | {016B332A-BEF3-496F-A896-3C5F2BC41238}.Debug|Any CPU.Build.0 = Debug|Any CPU 58 | {016B332A-BEF3-496F-A896-3C5F2BC41238}.Release|Any CPU.ActiveCfg = Release|Any CPU 59 | {016B332A-BEF3-496F-A896-3C5F2BC41238}.Release|Any CPU.Build.0 = Release|Any CPU 60 | {F745AB63-3DCF-48E3-AD87-93FE67012F72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 61 | {F745AB63-3DCF-48E3-AD87-93FE67012F72}.Debug|Any CPU.Build.0 = Debug|Any CPU 62 | {F745AB63-3DCF-48E3-AD87-93FE67012F72}.Release|Any CPU.ActiveCfg = Release|Any CPU 63 | {F745AB63-3DCF-48E3-AD87-93FE67012F72}.Release|Any CPU.Build.0 = Release|Any CPU 64 | {24DD7BAA-7B3A-420E-9D99-B0ADD7F41C5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 65 | {24DD7BAA-7B3A-420E-9D99-B0ADD7F41C5E}.Debug|Any CPU.Build.0 = Debug|Any CPU 66 | {24DD7BAA-7B3A-420E-9D99-B0ADD7F41C5E}.Release|Any CPU.ActiveCfg = Release|Any CPU 67 | {24DD7BAA-7B3A-420E-9D99-B0ADD7F41C5E}.Release|Any CPU.Build.0 = Release|Any CPU 68 | {C58E88D3-C68E-485B-9F37-92634216C182}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 69 | {C58E88D3-C68E-485B-9F37-92634216C182}.Debug|Any CPU.Build.0 = Debug|Any CPU 70 | {C58E88D3-C68E-485B-9F37-92634216C182}.Release|Any CPU.ActiveCfg = Release|Any CPU 71 | {C58E88D3-C68E-485B-9F37-92634216C182}.Release|Any CPU.Build.0 = Release|Any CPU 72 | EndGlobalSection 73 | GlobalSection(SolutionProperties) = preSolution 74 | HideSolutionNode = FALSE 75 | EndGlobalSection 76 | EndGlobal 77 | -------------------------------------------------------------------------------- /DFOToolbox/AboutWindow.xaml: -------------------------------------------------------------------------------- 1 |  12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | The source code for DFO Toolbox is available under the Apache 2.0 License at 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /DFOToolbox/AboutWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows; 8 | using System.Windows.Controls; 9 | using System.Windows.Data; 10 | using System.Windows.Documents; 11 | using System.Windows.Input; 12 | using System.Windows.Media; 13 | using System.Windows.Media.Imaging; 14 | using System.Windows.Shapes; 15 | 16 | namespace DFOToolbox 17 | { 18 | /// 19 | /// Interaction logic for About.xaml 20 | /// 21 | public partial class AboutWindow : Window 22 | { 23 | public AboutWindowViewModel ViewModel { get; set; } 24 | 25 | public AboutWindow() 26 | { 27 | ViewModel = new AboutWindowViewModel(); 28 | InitializeComponent(); 29 | } 30 | 31 | private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e) 32 | { 33 | try 34 | { 35 | using (Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri))) 36 | { 37 | ; 38 | } 39 | } 40 | catch (Exception) 41 | { 42 | // TODO: Log 43 | } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /DFOToolbox/AboutWindowViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DFOToolbox 8 | { 9 | public class AboutWindowViewModel 10 | { 11 | public string AppName { get; private set; } 12 | public string Version { get; private set; } 13 | public string Url { get; private set; } 14 | 15 | public AboutWindowViewModel() 16 | { 17 | AppName = "DFO Toolbox"; 18 | Url = "https://github.com/LHCGreg/DFOToolBox"; 19 | Version = typeof(AboutWindowViewModel).Assembly.GetName().Version.ToString(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /DFOToolbox/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /DFOToolbox/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /DFOToolbox/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | 8 | namespace DFOToolbox 9 | { 10 | /// 11 | /// Interaction logic for App.xaml 12 | /// 13 | public partial class App : Application 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /DFOToolbox/DFOToolbox.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {F745AB63-3DCF-48E3-AD87-93FE67012F72} 8 | WinExe 9 | Properties 10 | DFOToolbox 11 | DFOToolbox 12 | v4.5 13 | 512 14 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | 4 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | true 27 | true 28 | 29 | 30 | AnyCPU 31 | pdbonly 32 | true 33 | bin\Release\ 34 | TRACE 35 | prompt 36 | 4 37 | true 38 | true 39 | 40 | 41 | 42 | ..\packages\Prism.Composition.5.0.0\lib\NET45\Microsoft.Practices.Prism.Composition.dll 43 | 44 | 45 | ..\packages\Prism.Interactivity.5.0.0\lib\NET45\Microsoft.Practices.Prism.Interactivity.dll 46 | 47 | 48 | ..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.Mvvm.dll 49 | 50 | 51 | ..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.Mvvm.Desktop.dll 52 | 53 | 54 | ..\packages\Prism.PubSubEvents.1.0.0\lib\portable-sl4+wp7+windows8+net40\Microsoft.Practices.Prism.PubSubEvents.dll 55 | 56 | 57 | ..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.SharedInterfaces.dll 58 | 59 | 60 | ..\packages\CommonServiceLocator.1.2\lib\portable-windows8+net40+sl5+windowsphone8\Microsoft.Practices.ServiceLocation.dll 61 | 62 | 63 | 64 | 65 | 66 | 67 | 4.0 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | MSBuild:Compile 76 | Designer 77 | 78 | 79 | AboutWindow.xaml 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | Designer 97 | MSBuild:Compile 98 | 99 | 100 | MSBuild:Compile 101 | Designer 102 | 103 | 104 | App.xaml 105 | Code 106 | 107 | 108 | 109 | 110 | 111 | 112 | MainWindow.xaml 113 | Code 114 | 115 | 116 | 117 | 118 | 119 | Code 120 | 121 | 122 | True 123 | True 124 | Resources.resx 125 | 126 | 127 | True 128 | Settings.settings 129 | True 130 | 131 | 132 | ResXFileCodeGenerator 133 | Resources.Designer.cs 134 | 135 | 136 | 137 | SettingsSingleFileGenerator 138 | Settings.Designer.cs 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | {f96de472-94ce-46dc-89fe-049207cc9541} 148 | DFO.Common 149 | 150 | 151 | {44912ed2-024b-4ebf-b02f-910142c81e75} 152 | DFO.Images 153 | 154 | 155 | {04c832f4-8f9d-457a-99fe-cc33eaa98bfe} 156 | DFO.Npk 157 | 158 | 159 | {9aba11f3-61ac-4b40-8432-91b3fe9ca351} 160 | DFO.Utilities 161 | 162 | 163 | 164 | 165 | license.txt 166 | PreserveNewest 167 | 168 | 169 | graphicsmagick_licenses.txt 170 | PreserveNewest 171 | 172 | 173 | graphicsmagick_net_license.txt 174 | PreserveNewest 175 | 176 | 177 | sharpziplib_license.txt 178 | PreserveNewest 179 | 180 | 181 | 182 | 183 | readme.txt 184 | PreserveNewest 185 | 186 | 187 | 188 | 189 | msvcp110.dll 190 | PreserveNewest 191 | 192 | 193 | msvcr110.dll 194 | PreserveNewest 195 | 196 | 197 | 198 | 205 | -------------------------------------------------------------------------------- /DFOToolbox/DFOToolboxException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DFOToolbox 8 | { 9 | [Serializable] 10 | public class DFOToolboxException : Exception 11 | { 12 | public DFOToolboxException() { } 13 | public DFOToolboxException(string message) : base(message) { } 14 | public DFOToolboxException(string message, Exception inner) : base(message, inner) { } 15 | protected DFOToolboxException( 16 | System.Runtime.Serialization.SerializationInfo info, 17 | System.Runtime.Serialization.StreamingContext context) 18 | : base(info, context) { } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /DFOToolbox/DesignerMainWindowViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Media; 8 | using DFOToolbox.Models; 9 | using Microsoft.Practices.Prism.Commands; 10 | 11 | namespace DFOToolbox 12 | { 13 | /// 14 | /// Stub viewmodel for the main window used to provide data to be shown in the designer view in Visual Studio. 15 | /// 16 | public class DesignerMainWindowViewModel : IMainWindowViewModel 17 | { 18 | public InnerNpkFileList InnerFileList { get; set; } 19 | public FrameList FrameList { get; set; } 20 | public ImageSource CurrentFrameImage { get; set; } 21 | public string Status { get; set; } 22 | public string OpenNPKPath { get; set; } 23 | public bool CanOpen { get; set; } 24 | public bool CanQuickSaveAsPng { get; set; } 25 | 26 | public DesignerMainWindowViewModel() 27 | { 28 | InnerFileList = new InnerNpkFileList() 29 | { 30 | new InnerNpkFile("blahblahblah_0.img", "sprite/character/fighter/blahblahblah_0.img"), 31 | new InnerNpkFile("blahblahblah_1.img", "sprite/character/fighter/blahblahblah_1.img"), 32 | new InnerNpkFile("blahblahblah_2.img", "sprite/character/fighter/blahblahblah_2.img") 33 | }; 34 | 35 | InnerFileList.MoveCurrentToFirst(); 36 | 37 | FrameList = new FrameList() 38 | { 39 | new FrameMetadata(0, 85, 196, 200, 7, null), 40 | new FrameMetadata(1, 100, 185, 205, 15, null), 41 | new FrameMetadata(2, 100, 185, 205, 7, 0) 42 | }; 43 | 44 | CurrentFrameImage = null; 45 | Status = "I'm the status"; 46 | OpenNPKPath = @"C:\Neople\DFO\ImagePacks2\blah.NPK"; 47 | CanOpen = true; 48 | CanQuickSaveAsPng = true; 49 | } 50 | 51 | public void Open(string npkPath) 52 | { 53 | 54 | } 55 | 56 | public QuickSaveResults QuickSaveAsPng(string imgPath, int frameIndex) 57 | { 58 | return new QuickSaveResults() { Error = new DFOToolboxException("Designer viewmodel doesn't support saving.") }; 59 | } 60 | 61 | public bool CanEditFrame { get; set; } 62 | 63 | public void EditFrame(string imgPath, int frameIndex, string pngFilePath) 64 | { 65 | 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /DFOToolbox/IMainWindowViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Media; 7 | using DFOToolbox.Models; 8 | using Microsoft.Practices.Prism.Commands; 9 | 10 | namespace DFOToolbox 11 | { 12 | public interface IMainWindowViewModel 13 | { 14 | InnerNpkFileList InnerFileList { get; set; } 15 | FrameList FrameList { get; set; } 16 | ImageSource CurrentFrameImage { get; set; } 17 | string Status { get; set; } 18 | string OpenNPKPath { get; set; } 19 | 20 | void Open(string npkPath); 21 | bool CanOpen { get; set; } 22 | 23 | QuickSaveResults QuickSaveAsPng(string imgPath, int frameIndex); 24 | bool CanQuickSaveAsPng { get; set; } 25 | 26 | /// Something went wrong while editing. Message is suitable for UI display. 27 | /// Other errors resulting from incorrect usage of this function, such as passing null arguments or trying to edit a frame while no file is open. 28 | void EditFrame(string imgPath, int frameIndex, string pngFilePath); 29 | bool CanEditFrame { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /DFOToolbox/IMultiSelectCollectionView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows.Controls.Primitives; 7 | 8 | namespace DFOToolbox 9 | { 10 | // From http://grokys.blogspot.com/2010/07/mvvm-and-multiple-selection-part-iii.html 11 | public interface IMultiSelectCollectionView 12 | { 13 | void AddControl(Selector selector); 14 | void RemoveControl(Selector selector); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /DFOToolbox/ISelectable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DFOToolbox 8 | { 9 | public interface ISelectable 10 | { 11 | bool IsSelected { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /DFOToolbox/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 71 | 72 | 73 | 74 | 75 | x (, ) 76 | 77 | 78 | 79 | 80 | 81 | 82 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /DFOToolbox/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows; 3 | 4 | namespace DFOToolbox 5 | { 6 | /// 7 | /// Interaction logic for MainWindow.xaml 8 | /// 9 | public partial class MainWindow : Window, IDisposable 10 | { 11 | public MainWindowViewModel ViewModel { get; set; } 12 | public MainWindowViewCommands ViewCommands { get; set; } 13 | 14 | public MainWindow() 15 | { 16 | ViewModel = new MainWindowViewModel(); 17 | ViewCommands = new MainWindowViewCommands(this, ViewModel); 18 | InitializeComponent(); 19 | } 20 | 21 | public void Dispose() 22 | { 23 | if (ViewModel != null) 24 | { 25 | ViewModel.Dispose(); 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /DFOToolbox/Models/FrameList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Data; 8 | 9 | namespace DFOToolbox.Models 10 | { 11 | public class FrameList : StrongMultiSelectListCollectionView 12 | { 13 | public FrameList() 14 | { 15 | 16 | } 17 | 18 | public FrameList(ObservableCollection frames) 19 | : base(frames) 20 | { 21 | 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /DFOToolbox/Models/FrameMetadata.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Runtime.CompilerServices; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using DFO.Common.Images; 9 | 10 | namespace DFOToolbox.Models 11 | { 12 | public class FrameMetadata : NotifyPropertyChangedBase, ISelectable 13 | { 14 | private int _index; 15 | public int Index 16 | { 17 | get { return _index; } 18 | set { _index = value; OnPropertyChanged(); } 19 | } 20 | 21 | private bool _isSelected; 22 | public bool IsSelected 23 | { 24 | get { return _isSelected; } 25 | set { _isSelected = value; OnPropertyChanged(); } 26 | } 27 | 28 | public const string PropertyNameIsSelected = "IsSelected"; 29 | 30 | private int _width; 31 | public int Width 32 | { 33 | get { return _width; } 34 | set { _width = value; OnPropertyChanged(); } 35 | } 36 | 37 | private int _height; 38 | public int Height 39 | { 40 | get { return _height; } 41 | set { _height = value; OnPropertyChanged(); } 42 | } 43 | 44 | private int _x; 45 | public int X 46 | { 47 | get { return _x; } 48 | set { _x = value; OnPropertyChanged(); } 49 | } 50 | 51 | private int _y; 52 | public int Y 53 | { 54 | get { return _y; } 55 | set { _y = value; OnPropertyChanged(); } 56 | } 57 | 58 | // If this is set, the frame is a link frame. The other properties will be set to the values of the linked frame. 59 | private int? _linkFrameIndex; 60 | public int? LinkFrameIndex 61 | { 62 | get { return _linkFrameIndex; } 63 | set { _linkFrameIndex = value; OnPropertyChanged(); } 64 | } 65 | 66 | public FrameMetadata() 67 | { 68 | 69 | } 70 | 71 | public FrameMetadata(int index, int width, int height, int x, int y, int? linkFrameIndex) 72 | { 73 | _index = index; 74 | _width = width; 75 | _height = height; 76 | _x = x; 77 | _y = y; 78 | _linkFrameIndex = linkFrameIndex; 79 | } 80 | 81 | /// 82 | /// 83 | /// 84 | /// If the frame being constructed is a link frame, this parameter should be the linked frame. 85 | /// 86 | /// 87 | public FrameMetadata(FrameInfo frame, int index, int? linkFrameIndex) 88 | { 89 | _index = index; 90 | _width = frame.Width; 91 | _height = frame.Height; 92 | _x = frame.LocationX; 93 | _y = frame.LocationY; 94 | _linkFrameIndex = linkFrameIndex; 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /DFOToolbox/Models/InnerNpkFile.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Runtime.CompilerServices; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace DFOToolbox.Models 10 | { 11 | public class InnerNpkFile : NotifyPropertyChangedBase 12 | { 13 | private string _name; 14 | public string Name 15 | { 16 | get { return _name; } 17 | set { _name = value; OnPropertyChanged(); } 18 | } 19 | 20 | private string _path; 21 | public string Path 22 | { 23 | get { return _path; } 24 | set { _path = value; OnPropertyChanged(); } 25 | } 26 | 27 | public InnerNpkFile() 28 | { 29 | 30 | } 31 | 32 | public InnerNpkFile(string name, string path) 33 | { 34 | _name = name; 35 | _path = path; 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /DFOToolbox/Models/InnerNpkFileList.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Collections.Specialized; 5 | using System.ComponentModel; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Data; 10 | 11 | namespace DFOToolbox.Models 12 | { 13 | public class InnerNpkFileList : StrongListCollectionView 14 | { 15 | public InnerNpkFileList() 16 | { 17 | 18 | } 19 | 20 | public InnerNpkFileList(ObservableCollection files) 21 | : base(files) 22 | { 23 | 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /DFOToolbox/MultiSelect.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Windows; 7 | using System.Windows.Controls.Primitives; 8 | 9 | namespace DFOToolbox 10 | { 11 | // From http://grokys.blogspot.com/2010/07/mvvm-and-multiple-selection-part-iii.html 12 | public static class MultiSelect 13 | { 14 | static MultiSelect() 15 | { 16 | Selector.ItemsSourceProperty.OverrideMetadata(typeof(Selector), new FrameworkPropertyMetadata(ItemsSourceChanged)); 17 | } 18 | 19 | public static bool GetIsEnabled(Selector target) 20 | { 21 | return (bool)target.GetValue(IsEnabledProperty); 22 | } 23 | 24 | public static void SetIsEnabled(Selector target, bool value) 25 | { 26 | target.SetValue(IsEnabledProperty, value); 27 | } 28 | 29 | public static readonly DependencyProperty IsEnabledProperty = 30 | DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(MultiSelect), 31 | new UIPropertyMetadata(IsEnabledChanged)); 32 | 33 | static void IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e) 34 | { 35 | Selector selector = sender as Selector; 36 | IMultiSelectCollectionView collectionView = selector.ItemsSource as IMultiSelectCollectionView; 37 | 38 | if (selector != null && collectionView != null) 39 | { 40 | if ((bool)e.NewValue) 41 | { 42 | collectionView.AddControl(selector); 43 | } 44 | else 45 | { 46 | collectionView.RemoveControl(selector); 47 | } 48 | } 49 | } 50 | 51 | static void ItemsSourceChanged(object sender, DependencyPropertyChangedEventArgs e) 52 | { 53 | Selector selector = sender as Selector; 54 | 55 | if (GetIsEnabled(selector)) 56 | { 57 | IMultiSelectCollectionView oldCollectionView = e.OldValue as IMultiSelectCollectionView; 58 | IMultiSelectCollectionView newCollectionView = e.NewValue as IMultiSelectCollectionView; 59 | 60 | if (oldCollectionView != null) 61 | { 62 | oldCollectionView.RemoveControl(selector); 63 | } 64 | 65 | if (newCollectionView != null) 66 | { 67 | newCollectionView.AddControl(selector); 68 | } 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /DFOToolbox/MultiSelectCollectionView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Collections.ObjectModel; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using System.Windows.Controls; 9 | using System.Windows.Controls.Primitives; 10 | using System.Windows.Data; 11 | 12 | namespace DFOToolbox 13 | { 14 | // From http://grokys.blogspot.com/2010/07/mvvm-and-multiple-selection-part-iii.html 15 | public class MultiSelectCollectionView : ListCollectionView, IMultiSelectCollectionView 16 | { 17 | public MultiSelectCollectionView(IList list) 18 | : base(list) 19 | { 20 | SelectedItems = new ObservableCollection(); 21 | } 22 | 23 | void IMultiSelectCollectionView.AddControl(Selector selector) 24 | { 25 | this.controls.Add(selector); 26 | SetSelection(selector); 27 | selector.SelectionChanged += control_SelectionChanged; 28 | } 29 | 30 | void IMultiSelectCollectionView.RemoveControl(Selector selector) 31 | { 32 | if (this.controls.Remove(selector)) 33 | { 34 | selector.SelectionChanged -= control_SelectionChanged; 35 | } 36 | } 37 | 38 | public ObservableCollection SelectedItems { get; private set; } 39 | 40 | void SetSelection(Selector selector) 41 | { 42 | MultiSelector multiSelector = selector as MultiSelector; 43 | ListBox listBox = selector as ListBox; 44 | 45 | if (multiSelector != null) 46 | { 47 | multiSelector.SelectedItems.Clear(); 48 | 49 | foreach (T item in SelectedItems) 50 | { 51 | multiSelector.SelectedItems.Add(item); 52 | } 53 | } 54 | else if (listBox != null) 55 | { 56 | listBox.SelectedItems.Clear(); 57 | 58 | foreach (T item in SelectedItems) 59 | { 60 | listBox.SelectedItems.Add(item); 61 | } 62 | } 63 | } 64 | 65 | void control_SelectionChanged(object sender, SelectionChangedEventArgs e) 66 | { 67 | if (!this.ignoreSelectionChanged) 68 | { 69 | bool changed = false; 70 | 71 | this.ignoreSelectionChanged = true; 72 | 73 | try 74 | { 75 | foreach (T item in e.AddedItems) 76 | { 77 | if (!SelectedItems.Contains(item)) 78 | { 79 | SelectedItems.Add(item); 80 | changed = true; 81 | } 82 | } 83 | 84 | foreach (T item in e.RemovedItems) 85 | { 86 | if (SelectedItems.Remove(item)) 87 | { 88 | changed = true; 89 | } 90 | } 91 | 92 | if (changed) 93 | { 94 | foreach (Selector control in this.controls) 95 | { 96 | if (control != sender) 97 | { 98 | SetSelection(control); 99 | } 100 | } 101 | } 102 | } 103 | finally 104 | { 105 | this.ignoreSelectionChanged = false; 106 | } 107 | } 108 | } 109 | 110 | bool ignoreSelectionChanged; 111 | List controls = new List(); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /DFOToolbox/NotifyPropertyChangedBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Runtime.CompilerServices; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace DFOToolbox 10 | { 11 | public class NotifyPropertyChangedBase : INotifyPropertyChanged 12 | { 13 | public event PropertyChangedEventHandler PropertyChanged; 14 | 15 | protected void OnPropertyChanged([CallerMemberName]string caller = null) 16 | { 17 | PropertyChangedEventHandler handler = PropertyChanged; 18 | if (handler != null) 19 | { 20 | handler(this, new PropertyChangedEventArgs(caller)); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /DFOToolbox/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("DFOToolbox")] 11 | [assembly: AssemblyDescription("Graphical interface for extracting images from DFO's NPK files")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("")] 14 | [assembly: AssemblyProduct("DFO Toolbox")] 15 | [assembly: AssemblyCopyright("Copyright © LHCGreg 2015")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | // You can specify all the values or you can default the Build and Revision Numbers 52 | // by using the '*' as shown below: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("0.3.0.0")] 55 | [assembly: AssemblyFileVersion("0.3.0.0")] 56 | -------------------------------------------------------------------------------- /DFOToolbox/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34209 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace DFOToolbox.Properties { 12 | using System; 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources { 26 | 27 | private static global::System.Resources.ResourceManager resourceMan; 28 | 29 | private static global::System.Globalization.CultureInfo resourceCulture; 30 | 31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 32 | internal Resources() { 33 | } 34 | 35 | /// 36 | /// Returns the cached ResourceManager instance used by this class. 37 | /// 38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 39 | internal static global::System.Resources.ResourceManager ResourceManager { 40 | get { 41 | if (object.ReferenceEquals(resourceMan, null)) { 42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DFOToolbox.Properties.Resources", typeof(Resources).Assembly); 43 | resourceMan = temp; 44 | } 45 | return resourceMan; 46 | } 47 | } 48 | 49 | /// 50 | /// Overrides the current thread's CurrentUICulture property for all 51 | /// resource lookups using this strongly typed resource class. 52 | /// 53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 54 | internal static global::System.Globalization.CultureInfo Culture { 55 | get { 56 | return resourceCulture; 57 | } 58 | set { 59 | resourceCulture = value; 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /DFOToolbox/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 |  2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | text/microsoft-resx 107 | 108 | 109 | 2.0 110 | 111 | 112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 113 | 114 | 115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | -------------------------------------------------------------------------------- /DFOToolbox/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.34209 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace DFOToolbox.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /DFOToolbox/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /DFOToolbox/QuickSaveResults.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace DFOToolbox 8 | { 9 | public class QuickSaveResults 10 | { 11 | public string OutputPath { get; set; } 12 | public string OutputFolder { get; set; } 13 | public DFOToolboxException Error { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /DFOToolbox/StrongListCollectionView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.ComponentModel; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using System.Windows.Data; 9 | 10 | namespace DFOToolbox 11 | { 12 | public class StrongListCollectionView : ListCollectionView 13 | { 14 | public StrongListCollectionView() 15 | : base(new ObservableCollection()) 16 | { 17 | this.CurrentChanged += (sender, e) => OnPropertyChanged(new PropertyChangedEventArgs(PropNameCurrent)); 18 | } 19 | 20 | public StrongListCollectionView(ObservableCollection values) 21 | : base(values) 22 | { 23 | 24 | } 25 | 26 | public void Clear() 27 | { 28 | InternalList.Clear(); 29 | } 30 | 31 | public void Add(T item) 32 | { 33 | InternalList.Add(item); 34 | } 35 | 36 | private const string PropNameCurrent = "Current"; 37 | public T Current { get { return (T)CurrentItem; } } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /DFOToolbox/StrongMultiSelectListCollectionView.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Collections.ObjectModel; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using System.Windows.Data; 8 | 9 | namespace DFOToolbox 10 | { 11 | public class StrongMultiSelectListCollectionView : MultiSelectCollectionView 12 | where T : ISelectable 13 | { 14 | public StrongMultiSelectListCollectionView() 15 | : base(new ObservableCollection()) 16 | { 17 | 18 | } 19 | 20 | public StrongMultiSelectListCollectionView(ObservableCollection values) 21 | : base(values) 22 | { 23 | 24 | } 25 | 26 | public void Clear() 27 | { 28 | SelectedItems.Clear(); 29 | InternalList.Clear(); 30 | } 31 | 32 | public void Add(T item) 33 | { 34 | InternalList.Add(item); 35 | } 36 | 37 | public T Current { get { return (T)CurrentItem; } } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /DFOToolbox/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/msvcp2012x86/msvcp110.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LHCGreg/DFOToolBox/f8f45fb629c668020c793727c419a775759e78fc/lib/msvcp2012x86/msvcp110.dll -------------------------------------------------------------------------------- /lib/msvcp2012x86/msvcr110.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/LHCGreg/DFOToolBox/f8f45fb629c668020c793727c419a775759e78fc/lib/msvcp2012x86/msvcr110.dll -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. 10 | 11 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. 12 | 13 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. 14 | 15 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. 16 | 17 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. 18 | 19 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. 20 | 21 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). 22 | 23 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. 24 | 25 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." 26 | 27 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 28 | 29 | 2. Grant of Copyright License. 30 | 31 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 32 | 33 | 3. Grant of Patent License. 34 | 35 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 36 | 37 | 4. Redistribution. 38 | 39 | You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: 40 | 41 | 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and 42 | 43 | 2. You must cause any modified files to carry prominent notices stating that You changed the files; and 44 | 45 | 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and 46 | 47 | 4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. 48 | 49 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 50 | 51 | 5. Submission of Contributions. 52 | 53 | Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 54 | 55 | 6. Trademarks. 56 | 57 | This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 58 | 59 | 7. Disclaimer of Warranty. 60 | 61 | Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 62 | 63 | 8. Limitation of Liability. 64 | 65 | In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 66 | 67 | 9. Accepting Warranty or Additional Liability. 68 | 69 | While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. -------------------------------------------------------------------------------- /licenses/graphicsmagick_net_license.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. 10 | 11 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. 12 | 13 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. 14 | 15 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. 16 | 17 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. 18 | 19 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. 20 | 21 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). 22 | 23 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. 24 | 25 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." 26 | 27 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 28 | 29 | 2. Grant of Copyright License. 30 | 31 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 32 | 33 | 3. Grant of Patent License. 34 | 35 | Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 36 | 37 | 4. Redistribution. 38 | 39 | You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: 40 | 41 | 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and 42 | 43 | 2. You must cause any modified files to carry prominent notices stating that You changed the files; and 44 | 45 | 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and 46 | 47 | 4. If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. 48 | 49 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 50 | 51 | 5. Submission of Contributions. 52 | 53 | Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 54 | 55 | 6. Trademarks. 56 | 57 | This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 58 | 59 | 7. Disclaimer of Warranty. 60 | 61 | Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 62 | 63 | 8. Limitation of Liability. 64 | 65 | In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 66 | 67 | 9. Accepting Warranty or Additional Liability. 68 | 69 | While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. -------------------------------------------------------------------------------- /licenses/ndesk_options_license.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008 NDesk 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. -------------------------------------------------------------------------------- /licenses/readme.txt: -------------------------------------------------------------------------------- 1 | npk2gif is a command line tool for creating animated GIFs with transparent backgrounds from images in the .NPK files. The .NET Framework 4.5 is required to run npk2gif. There's a good chance you already have it installed. If you get an error box when you try to run it, you can get .NET 4.5 at https://www.microsoft.com/en-us/download/details.aspx?id=30653. 2 | 3 | Run 4 | 5 | npk2gif -h 6 | 7 | to get help. 8 | 9 | Example usage: 10 | 11 | npk2gif -npk C:\Neople\DFO\ImagePacks2\sprite_monster_impossible_bakal.NPK -img ashcore.img -frames 1-6 -delay 160 -o bakal_walk.gif 12 | 13 | 14 | 15 | DFO Toolbox is a GUI application for viewing the contents of Dungeon Fighter Online .NPK files. The .NET Framework 4.5 is required to run DFO Toolbox. There's a good chance you already have it installed. If you get an error box when you try to run it, you can get .NET 4.5 at https://www.microsoft.com/en-us/download/details.aspx?id=30653. 16 | 17 | 18 | 19 | npk2gif and DFO Toolbox are open source and are licensed under the Apache License 2.0 (license.txt). You can find the source code at https://github.com/LHCGreg/DFOToolBox. 20 | 21 | npk2gif and DFO Toolbox use the following software: 22 | 23 | GraphicsMagick.NET (https://graphicsmagick.codeplex.com/license), licensed under the Apache License 2.0 (graphicsmagick_net_license.txt). 24 | 25 | GraphicsMagick (http://www.graphicsmagick.org/index.html), licensed under various licenses (graphicsmagick_licenses.txt). 26 | 27 | SharpZipLib (http://icsharpcode.github.io/SharpZipLib/), licensed under the GPL with GNU Classpath exception, permitting distribution of linked binaries without providing source code (sharpziplib_license.txt). 28 | 29 | NDesk.Options is copyright NDesk.org and is licensed under the MIT/X11 license (ndesk_options_license.txt). 30 | 31 | Prism and Common Service Locator are copyright Microsoft. The license can be found at https://msdn.microsoft.com/en-us/library/gg405489(PandP.40).aspx. 32 | 33 | 34 | 35 | Thanks to Fiel for the initial reverse engineering work. -------------------------------------------------------------------------------- /licenses/sharpziplib_license.txt: -------------------------------------------------------------------------------- 1 | The library is released under the GPL with the following exception: 2 | 3 | Linking this library statically or dynamically with other modules is making a combined work based on this library. Thus, the terms and conditions of the GNU General Public License cover the whole combination. 4 | 5 | As a special exception, the copyright holders of this library give you permission to link this library with independent modules to produce an executable, regardless of the license terms of these independent modules, and to copy and distribute the resulting executable under terms of your choice, provided that you also meet, for each linked independent module, the terms and conditions of the license of that module. An independent module is a module which is not derived from or based on this library. If you modify this library, you may extend this exception to your version of the library, but you are not obligated to do so. If you do not wish to do so, delete this exception statement from your version. -------------------------------------------------------------------------------- /npk2gif/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /npk2gif/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using DFO.Common; 8 | using DFO.Common.Images; 9 | using DFO.Images; 10 | using DFO.Npk; 11 | using DFO.Utilities; 12 | using NDesk.Options; 13 | 14 | namespace DFO.npk2gif 15 | { 16 | class Program 17 | { 18 | static void Main(string[] args) 19 | { 20 | try 21 | { 22 | CommandLineArgs cmdLine = new CommandLineArgs(args); 23 | 24 | using (NpkReader npk = LoadNpk(cmdLine.NpkPath)) 25 | { 26 | NpkPath imgPath = GetImgPath(cmdLine, npk); 27 | 28 | RawAnimation animationData = new RawAnimation(); 29 | animationData.Loop = true; 30 | 31 | List frameInfo = GetFrameInfo(cmdLine, npk, imgPath); 32 | animationData.Frames = frameInfo; 33 | 34 | CreateOutputDir(cmdLine.OutputPath); 35 | 36 | using (FileStream gifOutputStream = OpenOutput(cmdLine.OutputPath)) 37 | using (GifMaker giffer = new GifMaker(npk, disposeImageSource: false)) 38 | { 39 | try 40 | { 41 | giffer.Create(animationData.AsConst(), gifOutputStream); 42 | } 43 | catch (Exception ex) 44 | { 45 | Console.Error.WriteLine("Error creating GIF: {0}", Utils.GetExceptionMessageWithInnerExceptions(ex)); 46 | Console.Error.WriteLine(ex.StackTrace); 47 | giffer.Dispose(); 48 | gifOutputStream.Dispose(); 49 | npk.Dispose(); 50 | Environment.Exit(1); 51 | } 52 | } 53 | } 54 | 55 | Console.WriteLine("GIF saved to {0}", cmdLine.OutputPath); 56 | } 57 | catch (OptionException ex) 58 | { 59 | Console.Error.WriteLine(ex.Message); 60 | Console.Error.WriteLine("Run with -h for help"); 61 | } 62 | catch (Exception ex) 63 | { 64 | Console.Error.WriteLine("Unexpected error: {0}", Utils.GetExceptionMessageWithInnerExceptions(ex)); 65 | Console.Error.WriteLine(ex.StackTrace); 66 | } 67 | } 68 | 69 | private static NpkReader LoadNpk(string path) 70 | { 71 | NpkReader npk = null; 72 | try 73 | { 74 | npk = new NpkReader(path); 75 | } 76 | catch (FileNotFoundException) 77 | { 78 | Console.Error.WriteLine("NPK file {0} not found.", path); 79 | Environment.Exit(1); 80 | } 81 | catch (UnauthorizedAccessException) 82 | { 83 | Console.Error.WriteLine("You do not have permission to read NPK file {0}", path); 84 | Environment.Exit(1); 85 | } 86 | catch (NpkException ex) 87 | { 88 | Console.Error.WriteLine("There was an error while loading the NPK file. The file format may have changed. Here is some information that may help debug the issue: {0}\n\n{1}", Utils.GetExceptionMessageWithInnerExceptions(ex), ex.StackTrace); 89 | Environment.Exit(1); 90 | } 91 | catch (Exception ex) 92 | { 93 | Console.Error.WriteLine("There was an error while loading the NPK file: {0}", ex.Message); 94 | Environment.Exit(1); 95 | } 96 | 97 | return npk; 98 | } 99 | 100 | private static NpkPath GetImgPath(CommandLineArgs cmdLine, NpkReader npk) 101 | { 102 | if (cmdLine.ImgPath != null) 103 | { 104 | NpkPath imgPath = new NpkPath(cmdLine.ImgPath); 105 | IList imgPathComponents = imgPath.GetPathComponents(); 106 | if (imgPathComponents.Count >= 1 && !imgPathComponents[0].Path.Equals("sprite", StringComparison.OrdinalIgnoreCase)) 107 | { 108 | // add sprite/ prefix if present 109 | imgPath = NpkPath.Combine("sprite", imgPath); 110 | } 111 | 112 | if (!npk.Images.ContainsKey(imgPath)) 113 | { 114 | Console.Error.WriteLine("There is no img file with path {0} in NPK file {1}", cmdLine.ImgPath, cmdLine.NpkPath); 115 | Environment.Exit(1); 116 | } 117 | 118 | return imgPath; 119 | } 120 | else 121 | { 122 | List matchingPaths = new List(); 123 | 124 | // Only the .img name was given. Look for it. 125 | foreach (NpkPath path in npk.Images.Keys) 126 | { 127 | if (path.GetFileName().Path.Equals(cmdLine.ImgName, StringComparison.OrdinalIgnoreCase)) 128 | { 129 | matchingPaths.Add(path); 130 | } 131 | } 132 | 133 | if (matchingPaths.Count == 1) 134 | { 135 | return matchingPaths[0]; 136 | } 137 | else if (matchingPaths.Count == 0) 138 | { 139 | Console.Error.WriteLine("There is no img file called {0} in NPK file {1}", cmdLine.ImgName, cmdLine.NpkPath); 140 | Environment.Exit(1); 141 | return null; // not reached 142 | } 143 | else 144 | { 145 | Console.Error.WriteLine("There are multiple img files matching the name {0} in NPK file {1}: {2}", cmdLine.ImgName, cmdLine.NpkPath, string.Join(", ", matchingPaths)); 146 | Environment.Exit(1); 147 | return null; // not reached 148 | } 149 | } 150 | } 151 | 152 | private static List GetFrameInfo(CommandLineArgs cmdLine, NpkReader npk, NpkPath imgPath) 153 | { 154 | List frameInfo = new List(); 155 | List frames = npk.Frames[imgPath].ToList(); 156 | 157 | if (cmdLine.UseAllFrames) 158 | { 159 | for (int frameIndex = 0; frameIndex < frames.Count; frameIndex++) 160 | { 161 | frameInfo.Add(new AnimationFrame() { DelayInMs = cmdLine.FrameDelayInMs, Image = new ImageIdentifier(imgPath, frameIndex) }.AsConst()); 162 | } 163 | } 164 | else 165 | { 166 | foreach (int frameIndex in cmdLine.FrameIndexes) 167 | { 168 | if (frameIndex >= frames.Count) 169 | { 170 | Console.Error.WriteLine("{0} in {1} has {2} frames in it, so frame index {3} is not valid.", imgPath, cmdLine.NpkPath, frames.Count, frameIndex); 171 | Environment.Exit(1); 172 | } 173 | frameInfo.Add(new AnimationFrame() { DelayInMs = cmdLine.FrameDelayInMs, Image = new ImageIdentifier(imgPath, frameIndex) }.AsConst()); 174 | } 175 | } 176 | 177 | return frameInfo; 178 | } 179 | 180 | private static void CreateOutputDir(string outputPath) 181 | { 182 | try 183 | { 184 | string directory = Path.GetDirectoryName(outputPath); 185 | if (string.IsNullOrWhiteSpace(directory)) 186 | { 187 | // relative path referring to a file in the current directory, like "output.gif" 188 | return; 189 | } 190 | Directory.CreateDirectory(directory); 191 | } 192 | catch (Exception ex) 193 | { 194 | Console.Error.WriteLine("Error creating output directory for {0}: {1}", outputPath, Utils.GetExceptionMessageWithInnerExceptions(ex)); 195 | Environment.Exit(1); 196 | } 197 | } 198 | 199 | private static FileStream OpenOutput(string outputPath) 200 | { 201 | try 202 | { 203 | return new FileStream(outputPath, FileMode.Create, FileAccess.ReadWrite, FileShare.None); 204 | } 205 | catch (Exception ex) 206 | { 207 | Console.Error.WriteLine("Error opening {0} for output: {1}", outputPath, Utils.GetExceptionMessageWithInnerExceptions(ex)); 208 | Environment.Exit(1); 209 | return null; // not reached 210 | } 211 | } 212 | } 213 | } 214 | -------------------------------------------------------------------------------- /npk2gif/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("npk2gif")] 9 | [assembly: AssemblyDescription("Makes animated GIFs from DFO NPK files")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DFO Toolbox")] 13 | [assembly: AssemblyCopyright("Copyright © LHCGreg 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("39ae6bc6-15a4-44b0-8ba1-7f26cfab481e")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("0.3.0.0")] 36 | [assembly: AssemblyFileVersion("0.3.0.0")] 37 | -------------------------------------------------------------------------------- /npk2gif/npk2gif.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D4F67769-4AE4-46CA-8442-D463DE903C21} 8 | Exe 9 | Properties 10 | DFO.npk2gif 11 | npk2gif 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | true 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | true 35 | 36 | 37 | 38 | ..\packages\NDesk.Options.0.2.1\lib\NDesk.Options.dll 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | Designer 53 | 54 | 55 | 56 | 57 | {f96de472-94ce-46dc-89fe-049207cc9541} 58 | DFO.Common 59 | 60 | 61 | {44912ed2-024b-4ebf-b02f-910142c81e75} 62 | DFO.Images 63 | 64 | 65 | {04c832f4-8f9d-457a-99fe-cc33eaa98bfe} 66 | DFO.Npk 67 | 68 | 69 | {9aba11f3-61ac-4b40-8432-91b3fe9ca351} 70 | DFO.Utilities 71 | 72 | 73 | 74 | 75 | msvcp110.dll 76 | PreserveNewest 77 | 78 | 79 | msvcr110.dll 80 | PreserveNewest 81 | 82 | 83 | license.txt 84 | PreserveNewest 85 | 86 | 87 | graphicsmagick_licenses.txt 88 | PreserveNewest 89 | 90 | 91 | graphicsmagick_net_license.txt 92 | PreserveNewest 93 | 94 | 95 | ndesk_options_license.txt 96 | PreserveNewest 97 | 98 | 99 | readme.txt 100 | PreserveNewest 101 | 102 | 103 | sharpziplib_license.txt 104 | PreserveNewest 105 | 106 | 107 | 108 | 115 | -------------------------------------------------------------------------------- /npk2gif/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /npkdiff/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /npkdiff/CommandLineArgs.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Reflection; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using NDesk.Options; 9 | 10 | namespace DFO.npkdiff 11 | { 12 | class CommandLineArgs 13 | { 14 | private bool m_showHelp = false; 15 | public bool ShowHelp { get { return m_showHelp; } private set { m_showHelp = value; } } 16 | 17 | private bool m_showVersion = false; 18 | public bool ShowVersion { get { return m_showVersion; } private set { m_showVersion = value; } } 19 | 20 | public string NpkDir1 { get; private set; } 21 | public string NpkDir2 { get; private set; } 22 | 23 | public CommandLineArgs(string[] args) 24 | { 25 | OptionSet optionSet = GetOptionSet(); 26 | 27 | try 28 | { 29 | optionSet.Parse(args); 30 | } 31 | catch (OptionException ex) 32 | { 33 | Console.Error.WriteLine(ex.Message); 34 | Environment.Exit(1); 35 | } 36 | 37 | if (ShowHelp) 38 | { 39 | DisplayHelp(Console.Error); 40 | Environment.Exit(0); 41 | } 42 | 43 | if (ShowVersion) 44 | { 45 | Console.WriteLine("{0} {1}", GetProgramNameWithoutExtension(), GetVersion()); 46 | Environment.Exit(0); 47 | } 48 | 49 | if (NpkDir1 == null || NpkDir2 == null) 50 | { 51 | DisplayHelp(Console.Error); 52 | Environment.Exit(1); 53 | } 54 | } 55 | 56 | public OptionSet GetOptionSet() 57 | { 58 | OptionSet optionSet = new OptionSet() 59 | { 60 | { "?|h|help", "Show this message and exit.", argExistence => ShowHelp = (argExistence != null) }, 61 | { "v|version", "Show version number and exit.", argExistence => ShowVersion = (argExistence != null) }, 62 | { "<>", AddDir } 63 | }; 64 | 65 | return optionSet; 66 | } 67 | 68 | private void AddDir(string arg) 69 | { 70 | if (NpkDir1 == null) 71 | { 72 | NpkDir1 = arg; 73 | } 74 | else if (NpkDir2 == null) 75 | { 76 | NpkDir2 = arg; 77 | } 78 | else 79 | { 80 | throw new OptionException(string.Format("More than 2 directories specified. Run {0} -h for help.", GetProgramNameWithoutExtension()), "<>"); 81 | } 82 | } 83 | 84 | public void DisplayHelp(TextWriter writer) 85 | { 86 | writer.WriteLine("Usage: {0} IMAGEPACKDIRECTORY1 IMAGEPACKDIRECTORY2", GetProgramNameWithoutExtension()); 87 | writer.WriteLine(); 88 | writer.WriteLine("Parameters:"); 89 | GetOptionSet().WriteOptionDescriptions(writer); 90 | } 91 | 92 | public static string GetProgramNameWithoutExtension() 93 | { 94 | string[] argsWithProgramName = System.Environment.GetCommandLineArgs(); 95 | string programName; 96 | if (argsWithProgramName[0].Equals(string.Empty)) 97 | { 98 | // "If the file name is not available, the first element is equal to String.Empty." 99 | // Doesn't say why that would happen, but ok... 100 | programName = (new AssemblyName(Assembly.GetExecutingAssembly().FullName).Name); 101 | } 102 | else 103 | { 104 | programName = Path.GetFileNameWithoutExtension(argsWithProgramName[0]); 105 | } 106 | 107 | return programName; 108 | } 109 | 110 | private static string GetVersion() 111 | { 112 | return typeof(CommandLineArgs).Assembly.GetName().Version.ToString(); 113 | } 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /npkdiff/FrameCountDifferenceInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using DFO.Common; 7 | 8 | namespace DFO.npkdiff 9 | { 10 | struct FrameCountDifferenceInfo 11 | { 12 | public int FrameCount1 { get; private set; } 13 | public string NpkFileName1 { get; private set; } 14 | public int FrameCount2 { get; private set; } 15 | public string NpkFileName2 { get; private set; } 16 | 17 | public FrameCountDifferenceInfo(int frameCount1, string npkFileName1, int frameCount2, string npkFileName2) 18 | : this() 19 | { 20 | FrameCount1 = frameCount1; 21 | FrameCount2 = frameCount2; 22 | NpkFileName1 = npkFileName1; 23 | NpkFileName2 = npkFileName2; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /npkdiff/ImgInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using DFO.Common; 7 | 8 | namespace DFO.npkdiff 9 | { 10 | struct ImgInfo 11 | { 12 | public string NpkFileName { get; private set; } 13 | public NpkPath Path { get; private set; } 14 | public int FrameCount { get; private set; } 15 | 16 | public ImgInfo(string npkFileName, NpkPath path, int frameCount) 17 | : this() 18 | { 19 | NpkFileName = npkFileName; 20 | Path = path; 21 | FrameCount = frameCount; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /npkdiff/NpkDirContents.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using DFO.Common; 7 | using DFO.Common.Images; 8 | 9 | namespace DFO.npkdiff 10 | { 11 | class NpkDirContents 12 | { 13 | private Dictionary _imgFrames; 14 | 15 | public NpkDirContents() 16 | { 17 | _imgFrames = new Dictionary(); 18 | } 19 | 20 | public NpkDirContents(string npkFilePath, IReadOnlyDictionary> frames) 21 | { 22 | _imgFrames = new Dictionary(frames.Count); 23 | foreach (NpkPath npkPath in frames.Keys) 24 | { 25 | _imgFrames[npkPath] = new ImgInfo(npkFilePath, npkPath, frames[npkPath].Count); 26 | } 27 | } 28 | 29 | public void Add(NpkDirContents other) 30 | { 31 | foreach (NpkPath npkPath in other._imgFrames.Keys) 32 | { 33 | if (!_imgFrames.ContainsKey(npkPath)) 34 | { 35 | _imgFrames[npkPath] = other._imgFrames[npkPath]; 36 | } 37 | } 38 | } 39 | 40 | public NpkDirDifferences GetDifferences(NpkDirContents other) 41 | { 42 | if (other == null) throw new ArgumentNullException("other"); 43 | 44 | List imgsInFirstButNotSecond = new List(); 45 | List imgsInSecondButNotFirst = new List(); 46 | Dictionary imgsWithFewerFramcesInSecond = new Dictionary(); 47 | Dictionary imgsWithMoreFramesInSecond = new Dictionary(); 48 | 49 | foreach (NpkPath npkPath in this._imgFrames.Keys) 50 | { 51 | if (!other._imgFrames.ContainsKey(npkPath)) 52 | { 53 | imgsInFirstButNotSecond.Add(this._imgFrames[npkPath]); 54 | } 55 | else 56 | { 57 | int thisFrameCount = this._imgFrames[npkPath].FrameCount; 58 | string thisNpkFilePath = this._imgFrames[npkPath].NpkFileName; 59 | int otherFrameCount = other._imgFrames[npkPath].FrameCount; 60 | string otherNpkFilePath = other._imgFrames[npkPath].NpkFileName; 61 | if (thisFrameCount > otherFrameCount) 62 | { 63 | imgsWithFewerFramcesInSecond[npkPath] = new FrameCountDifferenceInfo(thisFrameCount, thisNpkFilePath, otherFrameCount, otherNpkFilePath); 64 | } 65 | else if (thisFrameCount < otherFrameCount) 66 | { 67 | imgsWithMoreFramesInSecond[npkPath] = new FrameCountDifferenceInfo(thisFrameCount, thisNpkFilePath, otherFrameCount, otherNpkFilePath); 68 | } 69 | } 70 | } 71 | 72 | foreach (NpkPath npkPath in other._imgFrames.Keys) 73 | { 74 | if (!this._imgFrames.ContainsKey(npkPath)) 75 | { 76 | imgsInSecondButNotFirst.Add(other._imgFrames[npkPath]); 77 | } 78 | } 79 | 80 | return new NpkDirDifferences(imgsInFirstButNotSecond, imgsWithFewerFramcesInSecond, imgsInSecondButNotFirst, imgsWithMoreFramesInSecond); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /npkdiff/NpkDirDifferences.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using DFO.Common; 7 | 8 | namespace DFO.npkdiff 9 | { 10 | class NpkDirDifferences 11 | { 12 | public IReadOnlyList ImgsInFirstButNotSecond { get; private set; } 13 | public IReadOnlyDictionary ImgsWithFewerFramesInSecond { get; private set; } 14 | public IReadOnlyList ImgsInSecondButNotFirst { get; private set; } 15 | public IReadOnlyDictionary ImgsWithMoreFramesInSecond { get; private set; } 16 | 17 | public NpkDirDifferences(IReadOnlyList imgsInFirstButNotSecond, IReadOnlyDictionary imgsWithFewerFramesInSecond, IReadOnlyList imgsInSecondButNotFirst, IReadOnlyDictionary imgsWithMoreFramesInSecond) 18 | { 19 | ImgsInFirstButNotSecond = imgsInFirstButNotSecond; 20 | ImgsWithFewerFramesInSecond = imgsWithFewerFramesInSecond; 21 | ImgsInSecondButNotFirst = imgsInSecondButNotFirst; 22 | ImgsWithMoreFramesInSecond = imgsWithMoreFramesInSecond; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /npkdiff/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using DFO.Common; 8 | using DFO.Npk; 9 | 10 | namespace DFO.npkdiff 11 | { 12 | class Program 13 | { 14 | static void Main(string[] args) 15 | { 16 | try 17 | { 18 | CommandLineArgs cmdline = new CommandLineArgs(args); 19 | 20 | // read *.NPK in NpkDir1 21 | // read *.NPK in NpkDir2 22 | // Compare 23 | 24 | NpkDirContents dir1Contents = GetNpkDirContents(cmdline.NpkDir1); 25 | NpkDirContents dir2Contents = GetNpkDirContents(cmdline.NpkDir2); 26 | NpkDirDifferences differences = dir1Contents.GetDifferences(dir2Contents); 27 | DisplayDifferences(differences); 28 | } 29 | catch (Exception ex) 30 | { 31 | Console.Error.WriteLine("Unexpected error: {0}", ex.Message); 32 | } 33 | } 34 | 35 | static NpkDirContents GetNpkDirContents(string npkDir) 36 | { 37 | NpkDirContents allContents = new NpkDirContents(); 38 | foreach (string npkFilePath in Directory.GetFiles(npkDir, "*.NPK", SearchOption.TopDirectoryOnly)) 39 | { 40 | NpkDirContents npkContents = GetNpkContents(npkFilePath); 41 | allContents.Add(npkContents); 42 | } 43 | return allContents; 44 | } 45 | 46 | static NpkDirContents GetNpkContents(string npkFilePath) 47 | { 48 | using (NpkReader npk = new NpkReader(npkFilePath)) 49 | { 50 | return new NpkDirContents(Path.GetFileName(npkFilePath), npk.Frames); 51 | } 52 | } 53 | 54 | static void DisplayDifferences(NpkDirDifferences differences) 55 | { 56 | foreach (ImgInfo img in differences.ImgsInSecondButNotFirst.OrderBy(x => x.Path.Path)) 57 | { 58 | Console.WriteLine("+{0} ({1}): {2}", img.Path, img.FrameCount, img.NpkFileName); 59 | } 60 | foreach (NpkPath imgPath in differences.ImgsWithMoreFramesInSecond.Keys.OrderBy(x => x.Path)) 61 | { 62 | string npkFileNameDisplay; 63 | string npkFileName1 = differences.ImgsWithMoreFramesInSecond[imgPath].NpkFileName1; 64 | string npkFileName2 = differences.ImgsWithMoreFramesInSecond[imgPath].NpkFileName2; 65 | if (npkFileName1.Equals(npkFileName2, StringComparison.OrdinalIgnoreCase)) 66 | { 67 | npkFileNameDisplay = npkFileName1; 68 | } 69 | else 70 | { 71 | npkFileNameDisplay = string.Format("{0}->{1}", npkFileName1, npkFileName2); 72 | } 73 | Console.WriteLine(">{0} {1}->{2} {3}", imgPath, differences.ImgsWithMoreFramesInSecond[imgPath].FrameCount1, differences.ImgsWithMoreFramesInSecond[imgPath].FrameCount2, npkFileNameDisplay); 74 | } 75 | foreach (NpkPath imgPath in differences.ImgsWithFewerFramesInSecond.Keys.OrderBy(x => x.Path)) 76 | { 77 | string npkFileNameDisplay; 78 | string npkFileName1 = differences.ImgsWithFewerFramesInSecond[imgPath].NpkFileName1; 79 | string npkFileName2 = differences.ImgsWithFewerFramesInSecond[imgPath].NpkFileName2; 80 | if (npkFileName1.Equals(npkFileName2, StringComparison.OrdinalIgnoreCase)) 81 | { 82 | npkFileNameDisplay = npkFileName1; 83 | } 84 | else 85 | { 86 | npkFileNameDisplay = string.Format("{0}->{1}", npkFileName1, npkFileName2); 87 | } 88 | Console.WriteLine("<{0} {1}->{2}", imgPath, differences.ImgsWithFewerFramesInSecond[imgPath].FrameCount1, differences.ImgsWithFewerFramesInSecond[imgPath].FrameCount2, npkFileNameDisplay); 89 | } 90 | foreach (ImgInfo img in differences.ImgsInFirstButNotSecond.OrderBy(x => x.Path.Path)) 91 | { 92 | Console.WriteLine("-{0} ({1}): {2}", img.Path, img.FrameCount, img.NpkFileName); 93 | } 94 | } 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /npkdiff/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("npkdiff")] 9 | [assembly: AssemblyDescription("Reports on differences between two ImagePacks2 folders")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DFO Toolbox")] 13 | [assembly: AssemblyCopyright("Copyright © LHCGreg 2015")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("672be706-9215-42b8-b16d-59bda9484a5c")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /npkdiff/npkdiff.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {C58E88D3-C68E-485B-9F37-92634216C182} 8 | Exe 9 | Properties 10 | DFO.npkdiff 11 | npkdiff 12 | v4.5 13 | 512 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | true 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | true 35 | 36 | 37 | 38 | ..\packages\NDesk.Options.0.2.1\lib\NDesk.Options.dll 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | {f96de472-94ce-46dc-89fe-049207cc9541} 60 | DFO.Common 61 | 62 | 63 | {04c832f4-8f9d-457a-99fe-cc33eaa98bfe} 64 | DFO.Npk 65 | 66 | 67 | 68 | 75 | -------------------------------------------------------------------------------- /npkdiff/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /packages/repositories.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | This repository houses a library for reading Dungeon Fighter Online's packaged image files (.NPK files) and various DFO-related tools including: 2 | 3 | DFO Toolbox, a GUI application for viewing the contents of DFO's .NPK files. 4 | 5 | npk2gif, a command line tool for creating animated GIFs from images in NPK files. 6 | 7 | All code is licensed under the Apache License 2.0 (license.txt) unless stated otherwise. --------------------------------------------------------------------------------