diff --git a/build/NuSpecs/ImageProcessor.nuspec b/build/NuSpecs/ImageProcessor.nuspec
index 8041f5dfc..557d85150 100644
--- a/build/NuSpecs/ImageProcessor.nuspec
+++ b/build/NuSpecs/ImageProcessor.nuspec
@@ -25,8 +25,8 @@ Feedback is always welcome.
-
-
+
+
\ No newline at end of file
diff --git a/build/content/ImageProcessor/imageprocessor.targets b/build/content/ImageProcessor/imageprocessor.targets
index 0b161e3c5..f8de1a74b 100644
--- a/build/content/ImageProcessor/imageprocessor.targets
+++ b/build/content/ImageProcessor/imageprocessor.targets
@@ -14,7 +14,7 @@
+ DestinationFiles="@(NativeBinaries->'$(OutDir)\%(RecursiveDir)\%(Filename)%(Extension)')">
diff --git a/src/ImageProcessor.Web/NET45/Configuration/ImageProcessorConfiguration.cs b/src/ImageProcessor.Web/NET45/Configuration/ImageProcessorConfiguration.cs
index 89bcf39d7..9d3ea6be9 100644
--- a/src/ImageProcessor.Web/NET45/Configuration/ImageProcessorConfiguration.cs
+++ b/src/ImageProcessor.Web/NET45/Configuration/ImageProcessorConfiguration.cs
@@ -13,12 +13,16 @@ namespace ImageProcessor.Web.Configuration
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.IO;
using System.Linq;
using System.Reflection;
+ using System.Web;
using System.Web.Compilation;
using ImageProcessor.Common.Extensions;
using ImageProcessor.Processors;
+ using ImageProcessor.Web.Helpers;
using ImageProcessor.Web.Processors;
///
@@ -28,6 +32,12 @@ namespace ImageProcessor.Web.Configuration
public sealed class ImageProcessorConfiguration
{
#region Fields
+ ///
+ /// Whether the process is running in 64bit mode. Used for calling the correct dllimport method.
+ /// Clunky I know but I couldn't get dynamic methods to work.
+ ///
+ private static readonly bool Is64Bit = Environment.Is64BitProcess;
+
///
/// A new instance Initializes a new instance of the class.
/// with lazy initialization.
@@ -71,6 +81,7 @@ namespace ImageProcessor.Web.Configuration
///
private ImageProcessorConfiguration()
{
+ this.EnsureNativeBinariesLoaded();
this.LoadGraphicsProcessors();
}
#endregion
@@ -353,6 +364,38 @@ namespace ImageProcessor.Web.Configuration
webProcessor.Processor.Settings = this.GetPluginSettings(webProcessor.GetType().Name);
}
}
+
+ ///
+ /// Ensures that the native binaries are loaded.
+ ///
+ private void EnsureNativeBinariesLoaded()
+ {
+ string binary = Is64Bit ? "libwebp64.dll" : "libwebp32.dll";
+ string sourcePath = HttpContext.Current.Server.MapPath("~/bin");
+ string targetPath = new Uri(Assembly.GetExecutingAssembly().Location).LocalPath;
+ IntPtr pointer = IntPtr.Zero;
+
+ // Shadow copy the native binaries.
+ sourcePath = Path.Combine(sourcePath, binary);
+ targetPath = Path.GetFullPath(Path.Combine(targetPath, "..\\" + binary));
+
+ File.Copy(sourcePath, targetPath, true);
+
+ try
+ {
+ // Load the binary into memory.
+ pointer = NativeMethods.LoadLibrary(targetPath);
+ }
+ catch (Exception ex)
+ {
+ Debug.WriteLine(ex.Message);
+ }
+
+ if (pointer == IntPtr.Zero)
+ {
+ throw new ApplicationException("Cannot open " + binary);
+ }
+ }
#endregion
}
}
diff --git a/src/ImageProcessor.Web/NET45/Helpers/NativeMethods.cs b/src/ImageProcessor.Web/NET45/Helpers/NativeMethods.cs
new file mode 100644
index 000000000..9e983438c
--- /dev/null
+++ b/src/ImageProcessor.Web/NET45/Helpers/NativeMethods.cs
@@ -0,0 +1,44 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
+//
+//
+// Provides access to unmanaged native methods.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace ImageProcessor.Web.Helpers
+{
+ using System;
+ using System.Runtime.InteropServices;
+
+ ///
+ /// Provides access to unmanaged native methods.
+ ///
+ internal class NativeMethods
+ {
+ ///
+ /// Loads the specified module into the address space of the calling process.
+ /// The specified module may cause other modules to be loaded.
+ ///
+ ///
+ /// The name of the module. This can be either a library module or
+ /// an executable module.
+ ///
+ /// If the function succeeds, the return value is a handle to the module; otherwise null.
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
+ public static extern IntPtr LoadLibrary(string libname);
+
+ ///
+ /// Frees the loaded dynamic-link library (DLL) module and, if necessary, decrements its reference count.
+ /// When the reference count reaches zero, the module is unloaded from the address space of the calling
+ /// process and the handle is no longer valid.
+ ///
+ /// A handle to the loaded library module.
+ /// The LoadLibrary, LoadLibraryEx, GetModuleHandle, or GetModuleHandleEx function returns this handle.
+ /// If the function succeeds, the return value is nonzero; otherwise zero.
+ [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
+ public static extern bool FreeLibrary(IntPtr hModule);
+ }
+}
diff --git a/src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj b/src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj
index 7ca861264..ac434afe5 100644
--- a/src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj
+++ b/src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj
@@ -54,6 +54,7 @@
+
diff --git a/src/ImageProcessor.Web/NET45/Settings.StyleCop b/src/ImageProcessor.Web/NET45/Settings.StyleCop
new file mode 100644
index 000000000..09dd1de03
--- /dev/null
+++ b/src/ImageProcessor.Web/NET45/Settings.StyleCop
@@ -0,0 +1,7 @@
+
+
+
+ dllimport
+
+
+
\ No newline at end of file
diff --git a/src/ImageProcessor/Configuration/ImageProcessorBootstrapper.cs b/src/ImageProcessor/Configuration/ImageProcessorBootstrapper.cs
index e6a7f1962..a9d9c5542 100644
--- a/src/ImageProcessor/Configuration/ImageProcessorBootstrapper.cs
+++ b/src/ImageProcessor/Configuration/ImageProcessorBootstrapper.cs
@@ -12,7 +12,10 @@ namespace ImageProcessor.Configuration
{
using System;
using System.Collections.Generic;
+ using System.IO;
using System.Linq;
+ using System.Reflection;
+
using ImageProcessor.Common.Exceptions;
using ImageProcessor.Common.Extensions;
using ImageProcessor.Imaging.Formats;
diff --git a/src/ImageProcessor/ImageProcessor.csproj b/src/ImageProcessor/ImageProcessor.csproj
index 4521b06eb..1c5b26e80 100644
--- a/src/ImageProcessor/ImageProcessor.csproj
+++ b/src/ImageProcessor/ImageProcessor.csproj
@@ -130,10 +130,10 @@
-
+
PreserveNewest
-
+
PreserveNewest
diff --git a/src/ImageProcessor/Imaging/Formats/NativeMethods.cs b/src/ImageProcessor/Imaging/Formats/NativeMethods.cs
index 059c5259a..8aaff3432 100644
--- a/src/ImageProcessor/Imaging/Formats/NativeMethods.cs
+++ b/src/ImageProcessor/Imaging/Formats/NativeMethods.cs
@@ -37,7 +37,7 @@ namespace ImageProcessor.Imaging.Formats
///
/// 1 if success, otherwise error code returned in the case of (a) formatting error(s).
///
- [DllImport("x86\\libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPGetInfo")]
+ [DllImport("libwebp32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPGetInfo")]
public static extern int WebPGetInfo86(IntPtr data, uint dataSize, out int width, out int height);
///
@@ -58,7 +58,7 @@ namespace ImageProcessor.Imaging.Formats
///
/// 1 if success, otherwise error code returned in the case of (a) formatting error(s).
///
- [DllImport("x64\\libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPGetInfo")]
+ [DllImport("libwebp64.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPGetInfo")]
public static extern int WebPGetInfo64(IntPtr data, uint dataSize, out int width, out int height);
///
@@ -82,7 +82,7 @@ namespace ImageProcessor.Imaging.Formats
///
/// output_buffer if function succeeds; NULL otherwise
///
- [DllImport("x86\\libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPDecodeBGRAInto")]
+ [DllImport("libwebp32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPDecodeBGRAInto")]
public static extern IntPtr WebPDecodeBGRAInto86(IntPtr data, uint dataSize, IntPtr outputBuffer, int outputBufferSize, int outputStride);
///
@@ -106,7 +106,7 @@ namespace ImageProcessor.Imaging.Formats
///
/// output_buffer if function succeeds; NULL otherwise
///
- [DllImport("x64\\libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPDecodeBGRAInto")]
+ [DllImport("libwebp64.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPDecodeBGRAInto")]
public static extern IntPtr WebPDecodeBGRAInto64(IntPtr data, uint dataSize, IntPtr outputBuffer, int outputBufferSize, int outputStride);
///
@@ -133,7 +133,7 @@ namespace ImageProcessor.Imaging.Formats
///
/// Size of WebP Image
///
- [DllImport("x86\\libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPEncodeBGRA")]
+ [DllImport("libwebp32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPEncodeBGRA")]
public static extern int WebPEncodeBGRA86(IntPtr rgb, int width, int height, int stride, float qualityFactor, out IntPtr output);
///
@@ -160,7 +160,7 @@ namespace ImageProcessor.Imaging.Formats
///
/// Size of WebP Image
///
- [DllImport("x64\\libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPEncodeBGRA")]
+ [DllImport("libwebp64.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPEncodeBGRA")]
public static extern int WebPEncodeBGRA64(IntPtr rgb, int width, int height, int stride, float qualityFactor, out IntPtr output);
///
@@ -172,7 +172,7 @@ namespace ImageProcessor.Imaging.Formats
///
/// 1 if success, otherwise error code returned in the case of (a) error(s).
///
- [DllImport("x86\\libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPFree")]
+ [DllImport("libwebp32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPFree")]
public static extern int WebPFree86(IntPtr pointer);
///
@@ -184,7 +184,7 @@ namespace ImageProcessor.Imaging.Formats
///
/// 1 if success, otherwise error code returned in the case of (a) error(s).
///
- [DllImport("x64\\libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPFree")]
+ [DllImport("libwebp64.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPFree")]
public static extern int WebPFree64(IntPtr pointer);
#endregion
}
diff --git a/src/ImageProcessor/Imaging/Formats/WebPFormat.cs b/src/ImageProcessor/Imaging/Formats/WebPFormat.cs
index 25b0205e3..03f195122 100644
--- a/src/ImageProcessor/Imaging/Formats/WebPFormat.cs
+++ b/src/ImageProcessor/Imaging/Formats/WebPFormat.cs
@@ -32,7 +32,7 @@ namespace ImageProcessor.Imaging.Formats
public class WebPFormat : FormatBase
{
///
- /// Whether the process is running in 63bit mode. Used for calling the correct dllimport method.
+ /// Whether the process is running in 64bit mode. Used for calling the correct dllimport method.
/// Clunky I know but I couldn't get dynamic methods to work.
///
private static readonly bool Is64Bit = Environment.Is64BitProcess;
@@ -227,11 +227,6 @@ namespace ImageProcessor.Imaging.Formats
outputBuffer = NativeMethods.WebPDecodeBGRAInto86(ptrData, dataSize, outputBuffer, outputBufferSize, bitmapData.Stride);
}
- if (bitmapData.Scan0 != outputBuffer)
- {
- throw new ImageFormatException("Failed to decode WebP image with error " + (long)outputBuffer);
- }
-
// Write image to bitmap using Marshal
byte[] buffer = new byte[outputBufferSize];
Marshal.Copy(outputBuffer, buffer, 0, outputBufferSize);
diff --git a/src/ImageProcessor/x86/libwebp.dll.REMOVED.git-id b/src/ImageProcessor/libwebp32.dll.REMOVED.git-id
similarity index 100%
rename from src/ImageProcessor/x86/libwebp.dll.REMOVED.git-id
rename to src/ImageProcessor/libwebp32.dll.REMOVED.git-id
diff --git a/src/ImageProcessor/x64/libwebp.dll.REMOVED.git-id b/src/ImageProcessor/libwebp64.dll.REMOVED.git-id
similarity index 100%
rename from src/ImageProcessor/x64/libwebp.dll.REMOVED.git-id
rename to src/ImageProcessor/libwebp64.dll.REMOVED.git-id
diff --git a/src/ImageProcessorConsole/Program.cs b/src/ImageProcessorConsole/Program.cs
index 64053c5ed..b08b9440b 100644
--- a/src/ImageProcessorConsole/Program.cs
+++ b/src/ImageProcessorConsole/Program.cs
@@ -40,9 +40,9 @@ namespace ImageProcessorConsole
di.Create();
}
- FileInfo[] files = di.GetFiles("*.jpg");
+ //FileInfo[] files = di.GetFiles("*.jpg");
//FileInfo[] files = di.GetFiles();
- //var files = GetFilesByExtensions(di, ".gif", ".webp");
+ IEnumerable files = GetFilesByExtensions(di, ".gif", ".webp");
foreach (FileInfo fileInfo in files)
@@ -60,11 +60,11 @@ namespace ImageProcessorConsole
imageFactory.Load(inStream)
.AutoRotate()
.Constrain(size)
- .Format(new WebPFormat())
- .Quality(5)
+ //.Format(new WebPFormat())
+ //.Quality(5)
// ReSharper disable once AssignNullToNotNullAttribute
- .Save(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(path), @"..\..\images\output", Path.GetFileNameWithoutExtension(fileInfo.Name) + ".webp")));
- //.Save(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(path), @"..\..\images\output", fileInfo.Name)));
+ // .Save(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(path), @"..\..\images\output", Path.GetFileNameWithoutExtension(fileInfo.Name) + ".webp")));
+ .Save(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(path), @"..\..\images\output", fileInfo.Name)));
}
}
}
diff --git a/src/ImageProcessorConsole/images/output/rotate.webp b/src/ImageProcessorConsole/images/output/rotate.webp
deleted file mode 100644
index 8bc9002cd..000000000
--- a/src/ImageProcessorConsole/images/output/rotate.webp
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:37d346c1cc3fe9635397d508ee332740f1043f942d940871e4cfc3b616cf5279
-size 1792