Skip to content

Commit

Permalink
Added the option to duplicate the mask and have areas where the numbe…
Browse files Browse the repository at this point in the history
…r of surfaces exceeds the allowed number per tile

Updated the readme.md to reflect the new outputTiles mode
  • Loading branch information
pennyworth12345 committed Mar 26, 2017
1 parent de6258f commit 3bece8a
Show file tree
Hide file tree
Showing 21 changed files with 400 additions and 2 deletions.
Binary file modified .vs/MaskColorChecker/v14/.suo
Binary file not shown.
34 changes: 33 additions & 1 deletion MaskColorChecker/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ static void Main(string[] args)
int spacing = tileSize - (overlap * 2);
List<string> errors = new List<string>();

//creating copy of image for the purpose of drawing on the mask if the corresponding outputTiles value is selected
Image image = Image.FromFile(maskPath);
Graphics g = Graphics.FromImage(image);
bool needToSaveMask = false;

using (Bitmap maskImage = new Bitmap(maskPath))
{
for (int x = 0; x < tilesCount; x++)
Expand Down Expand Up @@ -137,13 +142,31 @@ static void Main(string[] args)
if (colors.Count > colorsPerTile)
{
//only needed if the user wants tiles outputted
if (outputTiles == 1)
if (outputTiles == 1 || outputTiles == 3)
{
//creating directory for bad tiles in the same directory as the original mask
string outputPath = Path.Combine(Path.GetDirectoryName(maskPath), "Bad_Tiles");
Directory.CreateDirectory(outputPath);
generatedTile.Save(Path.Combine(outputPath, tileName));
}
if (outputTiles == 2 || outputTiles == 3)
{
Color customColor = Color.FromArgb(255, Color.Gray);
SolidBrush shadowBrush = new SolidBrush(customColor);
if (tileRect.X > 5)
{
tileRect.X = tileRect.X - 5;
tileRect.Width = tileRect.Width + 10;
}
if (tileRect.Y > 5)
{
tileRect.Y = tileRect.Y - 5;
tileRect.Height = tileRect.Height + 10;
}
Pen myPen = new Pen(Color.FromArgb(255, 0, 0, 0), 10);
g.DrawRectangle(myPen, tileRect);
needToSaveMask = true;
}
errors.Add(string.Format("{0} had {1} colors", tileName, colors.Count));
List<Color> keyList = new List<Color>(colors.Keys);
for (int i = 0; i < keyList.Count; i++)
Expand All @@ -159,6 +182,15 @@ static void Main(string[] args)
}
}

//only save the duplicate mask if they have the correct outputTiles mode and there were more colors than allowed in a tile
if (needToSaveMask)
{
string imageNewPath = Path.Combine(Path.GetDirectoryName(maskPath), "Bad_Tiles");
string outputDir = Path.Combine(Path.GetDirectoryName(maskPath), "Bad_Tiles");
Directory.CreateDirectory(outputDir);
image.Save(Path.Combine(outputDir, "debugMask.bmp"));
}

for (int i = 0; i < errors.Count; i++)
{
Console.WriteLine(errors[i]);
Expand Down
Binary file added MaskColorChecker/bin/Debug/MaskColorChecker.exe
Binary file not shown.
6 changes: 6 additions & 0 deletions MaskColorChecker/bin/Debug/MaskColorChecker.exe.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>
Binary file added MaskColorChecker/bin/Debug/MaskColorChecker.pdb
Binary file not shown.
Binary file not shown.
6 changes: 6 additions & 0 deletions MaskColorChecker/bin/Debug/MaskColorChecker.vshost.exe.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>
Binary file modified MaskColorChecker/bin/Release/MaskColorChecker.exe
Binary file not shown.
Binary file modified MaskColorChecker/bin/Release/MaskColorChecker.pdb
Binary file not shown.
293 changes: 293 additions & 0 deletions MaskColorChecker/obj/Debug/Common.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,293 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Cryptography;
using System.Security.Principal;
using System.Text;
using System.Threading;

static class Common
{
private const int DelayUntilReboot = 4;

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, int dwFlags);

[DllImport("kernel32", SetLastError = true, CharSet = CharSet.Unicode)]
static extern IntPtr LoadLibrary(string dllToLoad);

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetDllDirectory(string lpPathName);

[Conditional("DEBUG")]
public static void Log(string format, params object[] args)
{
// Should this be trace?
Debug.WriteLine("=== COSTURA === " + string.Format(format, args));
}

static void CopyTo(Stream source, Stream destination)
{
var array = new byte[81920];
int count;
while ((count = source.Read(array, 0, array.Length)) != 0)
{
destination.Write(array, 0, count);
}
}

static void CreateDirectory(string tempBasePath)
{
if (!Directory.Exists(tempBasePath))
{
Directory.CreateDirectory(tempBasePath);
}
}

static byte[] ReadStream(Stream stream)
{
var data = new Byte[stream.Length];
stream.Read(data, 0, data.Length);
return data;
}

public static string CalculateChecksum(string filename)
{
using (FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (BufferedStream bs = new BufferedStream(fs))
{
using (SHA1Managed sha1 = new SHA1Managed())
{
byte[] hash = sha1.ComputeHash(bs);
StringBuilder formatted = new StringBuilder(2 * hash.Length);
foreach (byte b in hash)
{
formatted.AppendFormat("{0:X2}", b);
}
return formatted.ToString();
}
}
}

public static Assembly ReadExistingAssembly(AssemblyName name)
{
var currentDomain = AppDomain.CurrentDomain;
var assemblies = currentDomain.GetAssemblies();
foreach (var assembly in assemblies)
{
var currentName = assembly.GetName();
if (string.Equals(currentName.Name, name.Name, StringComparison.InvariantCultureIgnoreCase) &&
string.Equals(CultureToString(currentName.CultureInfo), CultureToString(name.CultureInfo), StringComparison.InvariantCultureIgnoreCase))
{
Log("Assembly '{0}' already loaded, returning existing assembly", assembly.FullName);

return assembly;
}
}
return null;
}

static string CultureToString(CultureInfo culture)
{
if (culture == null)
return "";

return culture.Name;
}

public static Assembly ReadFromDiskCache(string tempBasePath, AssemblyName requestedAssemblyName)
{
var name = requestedAssemblyName.Name.ToLowerInvariant();

if (requestedAssemblyName.CultureInfo != null && !String.IsNullOrEmpty(requestedAssemblyName.CultureInfo.Name))
name = String.Format("{0}.{1}", requestedAssemblyName.CultureInfo.Name, name);

var bittyness = IntPtr.Size == 8 ? "64" : "32";
var assemblyTempFilePath = Path.Combine(tempBasePath, String.Concat(name, ".dll"));
if (File.Exists(assemblyTempFilePath))
{
return Assembly.LoadFile(assemblyTempFilePath);
}
assemblyTempFilePath = Path.ChangeExtension(assemblyTempFilePath, "exe");
if (File.Exists(assemblyTempFilePath))
{
return Assembly.LoadFile(assemblyTempFilePath);
}
assemblyTempFilePath = Path.Combine(Path.Combine(tempBasePath, bittyness), String.Concat(name, ".dll"));
if (File.Exists(assemblyTempFilePath))
{
return Assembly.LoadFile(assemblyTempFilePath);
}
assemblyTempFilePath = Path.ChangeExtension(assemblyTempFilePath, "exe");
if (File.Exists(assemblyTempFilePath))
{
return Assembly.LoadFile(assemblyTempFilePath);
}
return null;
}

public static Assembly ReadFromEmbeddedResources(Dictionary<string, string> assemblyNames, Dictionary<string, string> symbolNames, AssemblyName requestedAssemblyName)
{
var name = requestedAssemblyName.Name.ToLowerInvariant();

if (requestedAssemblyName.CultureInfo != null && !String.IsNullOrEmpty(requestedAssemblyName.CultureInfo.Name))
name = String.Format("{0}.{1}", requestedAssemblyName.CultureInfo.Name, name);

byte[] assemblyData;
using (var assemblyStream = LoadStream(assemblyNames, name))
{
if (assemblyStream == null)
{
return null;
}
assemblyData = ReadStream(assemblyStream);
}

using (var pdbStream = LoadStream(symbolNames, name))
{
if (pdbStream != null)
{
var pdbData = ReadStream(pdbStream);
return Assembly.Load(assemblyData, pdbData);
}
}

return Assembly.Load(assemblyData);
}

static Stream LoadStream(Dictionary<string, string> resourceNames, string name)
{
string value;
if (resourceNames.TryGetValue(name, out value))
return LoadStream(value);

return null;
}

static Stream LoadStream(string fullname)
{
var executingAssembly = Assembly.GetExecutingAssembly();

if (fullname.EndsWith(".zip"))
{
using (var stream = executingAssembly.GetManifestResourceStream(fullname))
using (var compressStream = new DeflateStream(stream, CompressionMode.Decompress))
{
var memStream = new MemoryStream();
CopyTo(compressStream, memStream);
memStream.Position = 0;
return memStream;
}
}

return executingAssembly.GetManifestResourceStream(fullname);
}

// Mutex code from http://stackoverflow.com/questions/229565/what-is-a-good-pattern-for-using-a-global-mutex-in-c
public static void PreloadUnmanagedLibraries(string hash, string tempBasePath, IEnumerable<string> libs, Dictionary<string, string> checksums)
{
string mutexId = string.Format("Global\\Costura{0}", hash);

using (var mutex = new Mutex(false, mutexId))
{
var allowEveryoneRule = new MutexAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), MutexRights.FullControl, AccessControlType.Allow);
var securitySettings = new MutexSecurity();
securitySettings.AddAccessRule(allowEveryoneRule);
mutex.SetAccessControl(securitySettings);

var hasHandle = false;
try
{
try
{
hasHandle = mutex.WaitOne(60000, false);
if (hasHandle == false)
throw new TimeoutException("Timeout waiting for exclusive access");
}
catch (AbandonedMutexException)
{
hasHandle = true;
}

var bittyness = IntPtr.Size == 8 ? "64" : "32";
CreateDirectory(Path.Combine(tempBasePath, bittyness));
InternalPreloadUnmanagedLibraries(tempBasePath, libs, checksums);
}
finally
{
if (hasHandle)
mutex.ReleaseMutex();
}
}
}

static void InternalPreloadUnmanagedLibraries(string tempBasePath, IEnumerable<string> libs, Dictionary<string, string> checksums)
{
string name;

foreach (var lib in libs)
{
name = ResourceNameToPath(lib);

var assemblyTempFilePath = Path.Combine(tempBasePath, name);

if (File.Exists(assemblyTempFilePath))
{
var checksum = CalculateChecksum(assemblyTempFilePath);
if (checksum != checksums[lib])
File.Delete(assemblyTempFilePath);
}

if (!File.Exists(assemblyTempFilePath))
{
using (var copyStream = LoadStream(lib))
using (var assemblyTempFile = File.OpenWrite(assemblyTempFilePath))
{
CopyTo(copyStream, assemblyTempFile);
}
if (!MoveFileEx(assemblyTempFilePath, null, DelayUntilReboot))
{
//TODO: for now we ignore the return value.
}
}
}

SetDllDirectory(tempBasePath);

foreach (var lib in libs)
{
name = ResourceNameToPath(lib);

if (name.EndsWith(".dll"))
{
var assemblyTempFilePath = Path.Combine(tempBasePath, name);

LoadLibrary(assemblyTempFilePath);
}
}
}

static string ResourceNameToPath(string lib)
{
var bittyness = IntPtr.Size == 8 ? "64" : "32";

string name = lib;

if (lib.StartsWith(String.Concat("costura", bittyness, ".")))
name = Path.Combine(bittyness, lib.Substring(10));
else if (lib.StartsWith("costura."))
name = lib.Substring(8);

if (name.EndsWith(".zip"))
name = name.Substring(0, name.Length - 4);

return name;
}
}
Binary file not shown.
Binary file not shown.
Loading

0 comments on commit 3bece8a

Please sign in to comment.