Browse Source

Fixing asp native binary loading

Former-commit-id: e8e15db739bca8b30b9450e75a52588236364e85
af/merge-core
James South 12 years ago
parent
commit
6e58b734a7
  1. 4
      build/NuSpecs/ImageProcessor.nuspec
  2. 2
      build/content/ImageProcessor/imageprocessor.targets
  3. 43
      src/ImageProcessor.Web/NET45/Configuration/ImageProcessorConfiguration.cs
  4. 44
      src/ImageProcessor.Web/NET45/Helpers/NativeMethods.cs
  5. 1
      src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj
  6. 7
      src/ImageProcessor.Web/NET45/Settings.StyleCop
  7. 3
      src/ImageProcessor/Configuration/ImageProcessorBootstrapper.cs
  8. 4
      src/ImageProcessor/ImageProcessor.csproj
  9. 16
      src/ImageProcessor/Imaging/Formats/NativeMethods.cs
  10. 7
      src/ImageProcessor/Imaging/Formats/WebPFormat.cs
  11. 0
      src/ImageProcessor/libwebp32.dll.REMOVED.git-id
  12. 0
      src/ImageProcessor/libwebp64.dll.REMOVED.git-id
  13. 12
      src/ImageProcessorConsole/Program.cs
  14. 3
      src/ImageProcessorConsole/images/output/rotate.webp

4
build/NuSpecs/ImageProcessor.nuspec

@ -25,8 +25,8 @@ Feedback is always welcome.</description>
</metadata>
<files>
<file src="..\_BuildOutput\ImageProcessor\lib\ImageProcessor.dll" target="lib\ImageProcessor.dll" />
<file src="..\_BuildOutput\ImageProcessor\lib\x86\libwebp.dll" target="build\native\lib\x86\libwebp.dll" />
<file src="..\_BuildOutput\ImageProcessor\lib\x64\libwebp.dll" target="build\native\lib\x64\libwebp.dll" />
<file src="..\_BuildOutput\ImageProcessor\lib\libwebp32.dll" target="build\native\lib\libwebp32.dll" />
<file src="..\_BuildOutput\ImageProcessor\lib\libwebp64.dll" target="build\native\lib\libwebp64.dll" />
<file src="..\content\ImageProcessor\imageprocessor.targets" target="build\imageprocessor.targets" />
</files>
</package>

2
build/content/ImageProcessor/imageprocessor.targets

@ -14,7 +14,7 @@
</PropertyGroup>
<Target Name="CopyNativeBinaries" DependsOnTargets="CopyFilesToOutputDirectory">
<Copy SourceFiles="@(NativeBinaries)"
DestinationFiles="@(NativeBinaries->'$(OutDir)\%(RecursiveDir)\%(Filename).%(Extension)')">
DestinationFiles="@(NativeBinaries->'$(OutDir)\%(RecursiveDir)\%(Filename)%(Extension)')">
<Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
</Copy>
</Target>

43
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;
/// <summary>
@ -28,6 +32,12 @@ namespace ImageProcessor.Web.Configuration
public sealed class ImageProcessorConfiguration
{
#region Fields
/// <summary>
/// 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.
/// </summary>
private static readonly bool Is64Bit = Environment.Is64BitProcess;
/// <summary>
/// A new instance Initializes a new instance of the <see cref="T:ImageProcessor.Web.Config.ImageProcessorConfig"/> class.
/// with lazy initialization.
@ -71,6 +81,7 @@ namespace ImageProcessor.Web.Configuration
/// </summary>
private ImageProcessorConfiguration()
{
this.EnsureNativeBinariesLoaded();
this.LoadGraphicsProcessors();
}
#endregion
@ -353,6 +364,38 @@ namespace ImageProcessor.Web.Configuration
webProcessor.Processor.Settings = this.GetPluginSettings(webProcessor.GetType().Name);
}
}
/// <summary>
/// Ensures that the native binaries are loaded.
/// </summary>
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
}
}

44
src/ImageProcessor.Web/NET45/Helpers/NativeMethods.cs

@ -0,0 +1,44 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="NativeMethods.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Provides access to unmanaged native methods.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Web.Helpers
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// Provides access to unmanaged native methods.
/// </summary>
internal class NativeMethods
{
/// <summary>
/// Loads the specified module into the address space of the calling process.
/// The specified module may cause other modules to be loaded.
/// </summary>
/// <param name="libname">
/// The name of the module. This can be either a library module or
/// an executable module.
/// </param>
/// <returns>If the function succeeds, the return value is a handle to the module; otherwise null.</returns>
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr LoadLibrary(string libname);
/// <summary>
/// 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.
/// </summary>
/// <param name="hModule">A handle to the loaded library module.
/// The LoadLibrary, LoadLibraryEx, GetModuleHandle, or GetModuleHandleEx function returns this handle.</param>
/// <returns>If the function succeeds, the return value is nonzero; otherwise zero.</returns>
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public static extern bool FreeLibrary(IntPtr hModule);
}
}

1
src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj

@ -54,6 +54,7 @@
<Compile Include="Configuration\ImageProcessorConfiguration.cs" />
<Compile Include="Configuration\ImageSecuritySection.cs" />
<Compile Include="Helpers\CommonParameterParserUtility.cs" />
<Compile Include="Helpers\NativeMethods.cs" />
<Compile Include="Helpers\ResourceHelpers.cs" />
<Compile Include="Helpers\ImageHelpers.cs" />
<Compile Include="Helpers\RemoteFile.cs" />

7
src/ImageProcessor.Web/NET45/Settings.StyleCop

@ -0,0 +1,7 @@
<StyleCopSettings Version="105">
<GlobalSettings>
<CollectionProperty Name="RecognizedWords">
<Value>dllimport</Value>
</CollectionProperty>
</GlobalSettings>
</StyleCopSettings>

3
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;

4
src/ImageProcessor/ImageProcessor.csproj

@ -130,10 +130,10 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="x64\libwebp.dll">
<Content Include="libwebp64.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="x86\libwebp.dll">
<Content Include="libwebp32.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>

16
src/ImageProcessor/Imaging/Formats/NativeMethods.cs

@ -37,7 +37,7 @@ namespace ImageProcessor.Imaging.Formats
/// <returns>
/// 1 if success, otherwise error code returned in the case of (a) formatting error(s).
/// </returns>
[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);
/// <summary>
@ -58,7 +58,7 @@ namespace ImageProcessor.Imaging.Formats
/// <returns>
/// 1 if success, otherwise error code returned in the case of (a) formatting error(s).
/// </returns>
[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);
/// <summary>
@ -82,7 +82,7 @@ namespace ImageProcessor.Imaging.Formats
/// <returns>
/// output_buffer if function succeeds; NULL otherwise
/// </returns>
[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);
/// <summary>
@ -106,7 +106,7 @@ namespace ImageProcessor.Imaging.Formats
/// <returns>
/// output_buffer if function succeeds; NULL otherwise
/// </returns>
[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);
/// <summary>
@ -133,7 +133,7 @@ namespace ImageProcessor.Imaging.Formats
/// <returns>
/// Size of WebP Image
/// </returns>
[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);
/// <summary>
@ -160,7 +160,7 @@ namespace ImageProcessor.Imaging.Formats
/// <returns>
/// Size of WebP Image
/// </returns>
[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);
/// <summary>
@ -172,7 +172,7 @@ namespace ImageProcessor.Imaging.Formats
/// <returns>
/// 1 if success, otherwise error code returned in the case of (a) error(s).
/// </returns>
[DllImport("x86\\libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPFree")]
[DllImport("libwebp32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPFree")]
public static extern int WebPFree86(IntPtr pointer);
/// <summary>
@ -184,7 +184,7 @@ namespace ImageProcessor.Imaging.Formats
/// <returns>
/// 1 if success, otherwise error code returned in the case of (a) error(s).
/// </returns>
[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
}

7
src/ImageProcessor/Imaging/Formats/WebPFormat.cs

@ -32,7 +32,7 @@ namespace ImageProcessor.Imaging.Formats
public class WebPFormat : FormatBase
{
/// <summary>
/// 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.
/// </summary>
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);

0
src/ImageProcessor/x86/libwebp.dll.REMOVED.git-id → src/ImageProcessor/libwebp32.dll.REMOVED.git-id

0
src/ImageProcessor/x64/libwebp.dll.REMOVED.git-id → src/ImageProcessor/libwebp64.dll.REMOVED.git-id

12
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<FileInfo> 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)));
}
}
}

3
src/ImageProcessorConsole/images/output/rotate.webp

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:37d346c1cc3fe9635397d508ee332740f1043f942d940871e4cfc3b616cf5279
size 1792
Loading…
Cancel
Save