mirror of https://github.com/SixLabors/ImageSharp
Browse Source
Conflicts: src/ImageProcessor/Imaging/Formats/GifEncoder.cs src/ImageProcessorConsole/Program.cs src/ImageProcessorConsole/images/output/nLpfllv.gif Former-commit-id: 205a39fec955c7e11a238afa2dfa3eb1a5393ae4pull/17/head
28 changed files with 501 additions and 166 deletions
@ -0,0 +1,160 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="StringExtensionsUnitTests.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// Test harness for the string extensions
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Web.UnitTests.Extensions |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
using ImageProcessor.Web.Extensions; |
||||
|
using NUnit.Framework; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Test harness for the string extensions
|
||||
|
/// </summary>
|
||||
|
[TestFixture] |
||||
|
public class StringExtensionsUnitTests |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Tests the passing to an integer array
|
||||
|
/// </summary>
|
||||
|
[Test] |
||||
|
public void TestToIntegerArray() |
||||
|
{ |
||||
|
Dictionary<string, int[]> data = new Dictionary<string, int[]> |
||||
|
{ |
||||
|
{ |
||||
|
"123-456,78-90", |
||||
|
new[] { 123, 456, 78, 90 } |
||||
|
}, |
||||
|
{ |
||||
|
"87390174,741897498,74816,748297,57355", |
||||
|
new[] |
||||
|
{ |
||||
|
87390174, 741897498, 74816, |
||||
|
748297, 57355 |
||||
|
} |
||||
|
}, |
||||
|
{ "1-2-3", new[] { 1, 2, 3 } } |
||||
|
}; |
||||
|
|
||||
|
foreach (KeyValuePair<string, int[]> item in data) |
||||
|
{ |
||||
|
int[] result = item.Key.ToPositiveIntegerArray(); |
||||
|
Assert.AreEqual(item.Value, result); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Tests the passing to an float array
|
||||
|
/// </summary>
|
||||
|
[Test] |
||||
|
public void TestToFloatArray() |
||||
|
{ |
||||
|
Dictionary<string, float[]> data = new Dictionary<string, float[]> |
||||
|
{ |
||||
|
{ |
||||
|
"12.3-4.56,78-9.0", |
||||
|
new[] { 12.3F, 4.56F, 78, 9 } |
||||
|
}, |
||||
|
{ |
||||
|
"87390.174,7.41897498,748.16,748297,5.7355", |
||||
|
new[] |
||||
|
{ |
||||
|
87390.174F, 7.41897498F, |
||||
|
748.16F, 748297, 5.7355F |
||||
|
} |
||||
|
}, |
||||
|
{ "1-2-3", new float[] { 1, 2, 3 } } |
||||
|
}; |
||||
|
|
||||
|
foreach (KeyValuePair<string, float[]> item in data) |
||||
|
{ |
||||
|
float[] result = item.Key.ToPositiveFloatArray(); |
||||
|
Assert.AreEqual(item.Value, result); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Tests the MD5 fingerprint
|
||||
|
/// </summary>
|
||||
|
/// <param name="input">The input value</param>
|
||||
|
/// <param name="expected">The expected output of the hash</param>
|
||||
|
[Test] |
||||
|
[TestCase("test input", "2e7f7a62eabf0993239ca17c78c464d9")] |
||||
|
[TestCase("lorem ipsum dolor", "96ee002fee25e8b675a477c9750fa360")] |
||||
|
[TestCase("LoReM IpSuM DoLoR", "41e201da794c7fbdb8ce5526a71c8c83")] |
||||
|
[TestCase("1234567890", "e15e31c3d8898c92ab172a4311be9e84")] |
||||
|
public void TestToMd5Fingerprint(string input, string expected) |
||||
|
{ |
||||
|
string result = input.ToMD5Fingerprint(); |
||||
|
bool comparison = result.Equals(expected, StringComparison.InvariantCultureIgnoreCase); |
||||
|
Assert.True(comparison); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Tests the SHA-1 fingerprint
|
||||
|
/// </summary>
|
||||
|
/// <param name="input">The input value</param>
|
||||
|
/// <param name="expected">The expected output of the hash</param>
|
||||
|
[Test] |
||||
|
[TestCase("test input", "49883b34e5a0f48224dd6230f471e9dc1bdbeaf5")] |
||||
|
[TestCase("lorem ipsum dolor", "75899ad8827a32493928903aecd6e931bf36f967")] |
||||
|
[TestCase("LoReM IpSuM DoLoR", "2f44519afae72fc0837b72c6b53cb11338a1f916")] |
||||
|
[TestCase("1234567890", "01b307acba4f54f55aafc33bb06bbbf6ca803e9a")] |
||||
|
public void TestToSHA1Fingerprint(string input, string expected) |
||||
|
{ |
||||
|
string result = input.ToSHA1Fingerprint(); |
||||
|
bool comparison = result.Equals(expected, StringComparison.InvariantCultureIgnoreCase); |
||||
|
Assert.True(comparison); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Tests if the value is a valid URI path name. I.E the path part of a uri.
|
||||
|
/// </summary>
|
||||
|
/// <param name="input">The value to test</param>
|
||||
|
/// <param name="expected">Whether the value is correct</param>
|
||||
|
/// <remarks>
|
||||
|
/// The full RFC3986 does not seem to pass the test with the square brackets
|
||||
|
/// ':' is failing for some reason in VS but not elsewhere. Could be a build issue.
|
||||
|
/// </remarks>
|
||||
|
[Test] |
||||
|
[TestCase("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", true)] |
||||
|
[TestCase("-", true)] |
||||
|
[TestCase(".", true)] |
||||
|
[TestCase("_", true)] |
||||
|
[TestCase("~", true)] |
||||
|
[TestCase(":", true)] |
||||
|
[TestCase("/", true)] |
||||
|
[TestCase("?", true)] |
||||
|
[TestCase("#", false)] |
||||
|
[TestCase("[", false)] |
||||
|
[TestCase("]", false)]
|
||||
|
[TestCase("@", true)] |
||||
|
[TestCase("!", true)] |
||||
|
[TestCase("$", true)] |
||||
|
[TestCase("&", true)] |
||||
|
[TestCase("'", true)] |
||||
|
[TestCase("(", true)] |
||||
|
[TestCase(")", true)] |
||||
|
[TestCase("*", true)] |
||||
|
[TestCase("+", true)] |
||||
|
[TestCase(",", true)] |
||||
|
[TestCase(";", true)] |
||||
|
[TestCase("=", true)] |
||||
|
[TestCase("lorem ipsum", false)] |
||||
|
[TestCase("é", false)] |
||||
|
public void TestIsValidUriPathName(string input, bool expected) |
||||
|
{ |
||||
|
bool result = input.IsValidVirtualPathName(); |
||||
|
Assert.AreEqual(expected, result); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,159 @@ |
|||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
// <copyright file="ImageProcessorNativeBinaryModule.cs" company="James South">
|
||||
|
// Copyright (c) James South.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
// <summary>
|
||||
|
// The image processing native binary module.
|
||||
|
// </summary>
|
||||
|
// --------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
|
namespace ImageProcessor.Web.HttpModules |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using System.Reflection; |
||||
|
using System.Web; |
||||
|
|
||||
|
using ImageProcessor.Web.Helpers; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Controls the loading and unloading of any native binaries required by ImageProcessor.Web.
|
||||
|
/// </summary>
|
||||
|
public sealed class ImageProcessorNativeBinaryModule : IHttpModule |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Whether the process is running in 64bit mode. Used for calling the correct dllimport method.
|
||||
|
/// </summary>
|
||||
|
private static readonly bool Is64Bit = Environment.Is64BitProcess; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The object to lock against.
|
||||
|
/// </summary>
|
||||
|
private static readonly object SyncRoot = new object(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// The native binaries.
|
||||
|
/// </summary>
|
||||
|
private static readonly List<IntPtr> NativeBinaries = new List<IntPtr>(); |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// A value indicating whether this instance of the given entity has been disposed.
|
||||
|
/// </summary>
|
||||
|
/// <value><see langword="true"/> if this instance has been disposed; otherwise, <see langword="false"/>.</value>
|
||||
|
/// <remarks>
|
||||
|
/// If the entity is disposed, it must not be disposed a second
|
||||
|
/// time. The isDisposed field is set the first time the entity
|
||||
|
/// is disposed. If the isDisposed field is true, then the Dispose()
|
||||
|
/// method will not dispose again. This help not to prolong the entity's
|
||||
|
/// life in the Garbage Collector.
|
||||
|
/// </remarks>
|
||||
|
private bool isDisposed; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Disposes of the resources (other than memory) used by the module that implements
|
||||
|
/// <see cref="T:System.Web.IHttpModule" />.
|
||||
|
/// </summary>
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
if (this.isDisposed) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
// Call the appropriate methods to clean up
|
||||
|
// unmanaged resources here.
|
||||
|
lock (SyncRoot) |
||||
|
{ |
||||
|
this.FreeNativeBinaries(); |
||||
|
} |
||||
|
|
||||
|
// Note disposing is done.
|
||||
|
this.isDisposed = true; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a module and prepares it to handle requests.
|
||||
|
/// </summary>
|
||||
|
/// <param name="context">An <see cref="T:System.Web.HttpApplication" /> that provides access to
|
||||
|
/// the methods, properties, and events common to all application objects within an ASP.NET application</param>
|
||||
|
public void Init(HttpApplication context) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Loads any native ImageProcessor binaries.
|
||||
|
/// </summary>
|
||||
|
public void LoadNativeBinaries() |
||||
|
{ |
||||
|
lock (SyncRoot) |
||||
|
{ |
||||
|
this.RegisterNativeBinaries(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Registers any native binaries.
|
||||
|
/// </summary>
|
||||
|
/// <exception cref="ApplicationException">
|
||||
|
/// Thrown when a native binary cannot be loaded.
|
||||
|
/// </exception>
|
||||
|
private void RegisterNativeBinaries() |
||||
|
{ |
||||
|
if (NativeBinaries.Any()) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
string folder = Is64Bit ? "x64" : "x86"; |
||||
|
string sourcePath = HttpContext.Current.Server.MapPath("~/bin/" + folder); |
||||
|
string targetBasePath = new Uri(Assembly.GetExecutingAssembly().Location).LocalPath; |
||||
|
|
||||
|
DirectoryInfo directoryInfo = new DirectoryInfo(sourcePath); |
||||
|
if (directoryInfo.Exists) |
||||
|
{ |
||||
|
foreach (FileInfo fileInfo in directoryInfo.EnumerateFiles("*.dll")) |
||||
|
{ |
||||
|
if (fileInfo.Name.ToUpperInvariant().StartsWith("IMAGEPROCESSOR")) |
||||
|
{ |
||||
|
IntPtr pointer; |
||||
|
string targetPath = Path.GetFullPath(Path.Combine(targetBasePath, "..\\" + folder + "\\" + fileInfo.Name)); |
||||
|
File.Copy(sourcePath, targetPath, true); |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
// Load the binary into memory.
|
||||
|
pointer = NativeMethods.LoadLibrary(targetPath); |
||||
|
} |
||||
|
catch (Exception ex) |
||||
|
{ |
||||
|
throw new ApplicationException(ex.Message); |
||||
|
} |
||||
|
|
||||
|
if (pointer == IntPtr.Zero) |
||||
|
{ |
||||
|
throw new ApplicationException("Cannot load " + fileInfo.Name); |
||||
|
} |
||||
|
|
||||
|
NativeBinaries.Add(pointer); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Frees the reference to the native binaries.
|
||||
|
/// </summary>
|
||||
|
private void FreeNativeBinaries() |
||||
|
{ |
||||
|
foreach (IntPtr nativeBinary in NativeBinaries) |
||||
|
{ |
||||
|
// According to http://stackoverflow.com/a/2445558/427899 you need to call this twice.
|
||||
|
NativeMethods.FreeLibrary(nativeBinary); |
||||
|
NativeMethods.FreeLibrary(nativeBinary); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
After Width: | Height: | Size: 22 KiB |
Loading…
Reference in new issue