Browse Source

Reorganizing native binaries

Former-commit-id: f372775134cb759ae27a29d8703e11e8336403f1
af/merge-core
James South 12 years ago
parent
commit
dd6c62c43a
  1. 4
      build/NuSpecs/ImageProcessor.nuspec
  2. 2
      build/content/ImageProcessor.Web/web.config.transform
  3. 3
      src/ImageProcessor.Web/NET4/ImageProcessor.Web_NET4.csproj
  4. 29
      src/ImageProcessor.Web/NET45/Configuration/ImageProcessorConfiguration.cs
  5. 159
      src/ImageProcessor.Web/NET45/HttpModules/ImageProcessorNativeBinaryModule.cs
  6. 1
      src/ImageProcessor.Web/NET45/ImageProcessor.Web_NET45.csproj
  7. 1
      src/ImageProcessor.sln.DotSettings
  8. 5
      src/ImageProcessor/ImageProcessor.csproj
  9. 127
      src/ImageProcessor/Imaging/Formats/NativeMethods.cs
  10. 60
      src/ImageProcessor/Imaging/Formats/WebPFormat.cs
  11. 0
      src/ImageProcessor/x64/imageprocessor.libwebp.dll.REMOVED.git-id
  12. 0
      src/ImageProcessor/x86/imageprocessor.libwebp.dll.REMOVED.git-id
  13. 4
      src/ImageProcessorConsole/Program.cs
  14. 2
      src/ImageProcessorConsole/images/output/120430.gif.REMOVED.git-id
  15. 2
      src/ImageProcessorConsole/images/output/Tl4Yb.gif.REMOVED.git-id
  16. 2
      src/ImageProcessorConsole/images/output/nLpfllv.gif.REMOVED.git-id
  17. 3
      src/ImageProcessorConsole/images/output/rotate.jpg
  18. 4
      src/TestWebsites/NET45/Test_Website_NET45/Web.config

4
build/NuSpecs/ImageProcessor.nuspec

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

2
build/content/ImageProcessor.Web/web.config.transform

@ -3,6 +3,7 @@
<system.web> <system.web>
<httpModules> <httpModules>
<add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web"/> <add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web"/>
<add name="ImageProcessorNativeBinaryModule" type="ImageProcessor.Web.HttpModules.ImageProcessorNativeBinaryModule, ImageProcessor.Web"/>
</httpModules> </httpModules>
</system.web> </system.web>
<system.webServer> <system.webServer>
@ -13,6 +14,7 @@
</staticContent> </staticContent>
<modules> <modules>
<add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web"/> <add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web"/>
<add name="ImageProcessorNativeBinaryModule" type="ImageProcessor.Web.HttpModules.ImageProcessorNativeBinaryModule, ImageProcessor.Web"/>
</modules> </modules>
</system.webServer> </system.webServer>
</configuration> </configuration>

3
src/ImageProcessor.Web/NET4/ImageProcessor.Web_NET4.csproj

@ -116,6 +116,9 @@
</Compile> </Compile>
<Compile Include="..\NET45\Helpers\TaskHelpers.cs" /> <Compile Include="..\NET45\Helpers\TaskHelpers.cs" />
<Compile Include="..\NET45\HttpModules\ImageProcessingModule.cs" /> <Compile Include="..\NET45\HttpModules\ImageProcessingModule.cs" />
<Compile Include="..\NET45\HttpModules\ImageProcessorNativeBinaryModule.cs">
<Link>ImageProcessorNativeBinaryModule.cs</Link>
</Compile>
<Compile Include="..\NET45\ImageFactoryExtensions.cs" /> <Compile Include="..\NET45\ImageFactoryExtensions.cs" />
<Compile Include="..\NET45\Processors\Alpha.cs"> <Compile Include="..\NET45\Processors\Alpha.cs">
<Link>Alpha.cs</Link> <Link>Alpha.cs</Link>

29
src/ImageProcessor.Web/NET45/Configuration/ImageProcessorConfiguration.cs

@ -23,6 +23,7 @@ namespace ImageProcessor.Web.Configuration
using ImageProcessor.Common.Extensions; using ImageProcessor.Common.Extensions;
using ImageProcessor.Processors; using ImageProcessor.Processors;
using ImageProcessor.Web.Helpers; using ImageProcessor.Web.Helpers;
using ImageProcessor.Web.HttpModules;
using ImageProcessor.Web.Processors; using ImageProcessor.Web.Processors;
/// <summary> /// <summary>
@ -370,30 +371,14 @@ namespace ImageProcessor.Web.Configuration
/// </summary> /// </summary>
private void EnsureNativeBinariesLoaded() private void EnsureNativeBinariesLoaded()
{ {
string binary = Is64Bit ? "libwebp64.dll" : "libwebp32.dll"; // Load the correct method from the native binary module.
string sourcePath = HttpContext.Current.Server.MapPath("~/bin"); // We do it here as on init will cause an UnauthorizedAccessException.
string targetPath = new Uri(Assembly.GetExecutingAssembly().Location).LocalPath; HttpModuleCollection modules = HttpContext.Current.ApplicationInstance.Modules;
IntPtr pointer = IntPtr.Zero; ImageProcessorNativeBinaryModule nativeBinaryModule = modules.Get("ImageProcessorNativeBinaryModule") as ImageProcessorNativeBinaryModule;
// Shadow copy the native binaries. if (nativeBinaryModule != null)
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); nativeBinaryModule.LoadNativeBinaries();
} }
} }
#endregion #endregion

159
src/ImageProcessor.Web/NET45/HttpModules/ImageProcessorNativeBinaryModule.cs

@ -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);
}
}
}
}

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

@ -62,6 +62,7 @@
<Compile Include="Helpers\RemoteFile.cs" /> <Compile Include="Helpers\RemoteFile.cs" />
<Compile Include="Helpers\TaskHelpers.cs" /> <Compile Include="Helpers\TaskHelpers.cs" />
<Compile Include="HttpModules\ImageProcessingModule.cs" /> <Compile Include="HttpModules\ImageProcessingModule.cs" />
<Compile Include="HttpModules\ImageProcessorNativeBinaryModule.cs" />
<Compile Include="ImageFactoryExtensions.cs" /> <Compile Include="ImageFactoryExtensions.cs" />
<Compile Include="Processors\Alpha.cs" /> <Compile Include="Processors\Alpha.cs" />
<Compile Include="Processors\AutoRotate.cs" /> <Compile Include="Processors\AutoRotate.cs" />

1
src/ImageProcessor.sln.DotSettings

@ -1,4 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation"> <wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BGRA/@EntryIndexedValue">BGRA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BPP/@EntryIndexedValue">BPP</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BPP/@EntryIndexedValue">BPP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DT/@EntryIndexedValue">DT</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DT/@EntryIndexedValue">DT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FPX/@EntryIndexedValue">FPX</s:String> <s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FPX/@EntryIndexedValue">FPX</s:String>

5
src/ImageProcessor/ImageProcessor.csproj

@ -130,13 +130,14 @@
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="libwebp64.dll"> <Content Include="x64\imageprocessor.libwebp.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="libwebp32.dll"> <Content Include="x86\imageprocessor.libwebp.dll">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
</ItemGroup> </ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" /> <Import Project="$(SolutionDir)\.nuget\NuGet.targets" Condition="Exists('$(SolutionDir)\.nuget\NuGet.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. <!-- To modify your build process, add your task inside one of the targets below and uncomment it.

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

@ -43,8 +43,103 @@ namespace ImageProcessor.Imaging.Formats
/// <returns> /// <returns>
/// 1 if success, otherwise error code returned in the case of (a) formatting error(s). /// 1 if success, otherwise error code returned in the case of (a) formatting error(s).
/// </returns> /// </returns>
[DllImport("libwebp32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPGetInfo")] public static int WebPGetInfo(IntPtr data, uint dataSize, out int width, out int height)
public static extern int WebPGetInfo86(IntPtr data, uint dataSize, out int width, out int height); {
return Is64Bit ? WebPGetInfo64(data, dataSize, out width, out height)
: WebPGetInfo86(data, dataSize, out width, out height);
}
/// <summary>
/// Decode WEBP image pointed to by *data and returns BGR samples into a pre-allocated buffer
/// </summary>
/// <param name="data">
/// Pointer to WebP image data
/// </param>
/// <param name="dataSize">
/// This is the size of the memory block pointed to by data containing the image data
/// </param>
/// <param name="outputBuffer">
/// Pointer to decoded WebP image
/// </param>
/// <param name="outputBufferSize">
/// Size of allocated buffer
/// </param>
/// <param name="outputStride">
/// Specifies the distance between scan-lines
/// </param>
/// <returns>
/// output_buffer if function succeeds; NULL otherwise
/// </returns>
public static IntPtr WebPDecodeBGRAInto(IntPtr data, uint dataSize, IntPtr outputBuffer, int outputBufferSize, int outputStride)
{
return Is64Bit ? WebPDecodeBGRAInto64(data, dataSize, outputBuffer, outputBufferSize, outputStride)
: WebPDecodeBGRAInto86(data, dataSize, outputBuffer, outputBufferSize, outputStride);
}
/// <summary>
/// Lossy encoding images pointed to by *data in WebP format
/// </summary>
/// <param name="rgb">
/// Pointer to RGB image data
/// </param>
/// <param name="width">
/// The width range is limited currently from 1 to 16383
/// </param>
/// <param name="height">
/// The height range is limited currently from 1 to 16383
/// </param>
/// <param name="stride">
/// The stride.
/// </param>
/// <param name="qualityFactor">
/// Ranges from 0 (lower quality) to 100 (highest quality). Controls the loss and quality during compression
/// </param>
/// <param name="output">
/// output_buffer with WebP image
/// </param>
/// <returns>
/// Size of WebP Image
/// </returns>
public static int WebPEncodeBGRA(IntPtr rgb, int width, int height, int stride, float qualityFactor, out IntPtr output)
{
return Is64Bit ? WebPEncodeBGRA64(rgb, width, height, stride, qualityFactor, out output)
: WebPEncodeBGRA86(rgb, width, height, stride, qualityFactor, out output);
}
/// <summary>
/// Frees the unmanaged memory.
/// </summary>
/// <param name="pointer">
/// The pointer.
/// </param>
/// <returns>
/// 1 if success, otherwise error code returned in the case of (a) error(s).
/// </returns>
public static int WebPFree(IntPtr pointer)
{
return Is64Bit ? WebPFree64(pointer) : WebPFree86(pointer);
}
/// <summary>
/// Validate the WebP image header and retrieve the image height and width. Pointers *width and *height can be passed NULL if deemed irrelevant
/// </summary>
/// <param name="data">
/// Pointer to WebP image data
/// </param>
/// <param name="dataSize">
/// This is the size of the memory block pointed to by data containing the image data
/// </param>
/// <param name="width">
/// The width range is limited currently from 1 to 16383
/// </param>
/// <param name="height">
/// The height range is limited currently from 1 to 16383
/// </param>
/// <returns>
/// 1 if success, otherwise error code returned in the case of (a) formatting error(s).
/// </returns>
[DllImport("x86\\imageprocessor.libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPGetInfo")]
private static extern int WebPGetInfo86(IntPtr data, uint dataSize, out int width, out int height);
/// <summary> /// <summary>
/// Validate the WebP image header and retrieve the image height and width. Pointers *width and *height can be passed NULL if deemed irrelevant /// Validate the WebP image header and retrieve the image height and width. Pointers *width and *height can be passed NULL if deemed irrelevant
@ -64,8 +159,8 @@ namespace ImageProcessor.Imaging.Formats
/// <returns> /// <returns>
/// 1 if success, otherwise error code returned in the case of (a) formatting error(s). /// 1 if success, otherwise error code returned in the case of (a) formatting error(s).
/// </returns> /// </returns>
[DllImport("libwebp64.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPGetInfo")] [DllImport("x64\\imageprocessor.libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPGetInfo")]
public static extern int WebPGetInfo64(IntPtr data, uint dataSize, out int width, out int height); private static extern int WebPGetInfo64(IntPtr data, uint dataSize, out int width, out int height);
/// <summary> /// <summary>
/// Decode WEBP image pointed to by *data and returns BGR samples into a pre-allocated buffer /// Decode WEBP image pointed to by *data and returns BGR samples into a pre-allocated buffer
@ -88,8 +183,8 @@ namespace ImageProcessor.Imaging.Formats
/// <returns> /// <returns>
/// output_buffer if function succeeds; NULL otherwise /// output_buffer if function succeeds; NULL otherwise
/// </returns> /// </returns>
[DllImport("libwebp32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPDecodeBGRAInto")] [DllImport("x86\\imageprocessor.libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPDecodeBGRAInto")]
public static extern IntPtr WebPDecodeBGRAInto86(IntPtr data, uint dataSize, IntPtr outputBuffer, int outputBufferSize, int outputStride); private static extern IntPtr WebPDecodeBGRAInto86(IntPtr data, uint dataSize, IntPtr outputBuffer, int outputBufferSize, int outputStride);
/// <summary> /// <summary>
/// Decode WEBP image pointed to by *data and returns BGR samples into a pre-allocated buffer /// Decode WEBP image pointed to by *data and returns BGR samples into a pre-allocated buffer
@ -112,8 +207,8 @@ namespace ImageProcessor.Imaging.Formats
/// <returns> /// <returns>
/// output_buffer if function succeeds; NULL otherwise /// output_buffer if function succeeds; NULL otherwise
/// </returns> /// </returns>
[DllImport("libwebp64.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPDecodeBGRAInto")] [DllImport("x64\\imageprocessor.libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPDecodeBGRAInto")]
public static extern IntPtr WebPDecodeBGRAInto64(IntPtr data, uint dataSize, IntPtr outputBuffer, int outputBufferSize, int outputStride); private static extern IntPtr WebPDecodeBGRAInto64(IntPtr data, uint dataSize, IntPtr outputBuffer, int outputBufferSize, int outputStride);
/// <summary> /// <summary>
/// Lossy encoding images pointed to by *data in WebP format /// Lossy encoding images pointed to by *data in WebP format
@ -139,8 +234,8 @@ namespace ImageProcessor.Imaging.Formats
/// <returns> /// <returns>
/// Size of WebP Image /// Size of WebP Image
/// </returns> /// </returns>
[DllImport("libwebp32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPEncodeBGRA")] [DllImport("x86\\imageprocessor.libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPEncodeBGRA")]
public static extern int WebPEncodeBGRA86(IntPtr rgb, int width, int height, int stride, float qualityFactor, out IntPtr output); private static extern int WebPEncodeBGRA86(IntPtr rgb, int width, int height, int stride, float qualityFactor, out IntPtr output);
/// <summary> /// <summary>
/// Lossy encoding images pointed to by *data in WebP format /// Lossy encoding images pointed to by *data in WebP format
@ -166,8 +261,8 @@ namespace ImageProcessor.Imaging.Formats
/// <returns> /// <returns>
/// Size of WebP Image /// Size of WebP Image
/// </returns> /// </returns>
[DllImport("libwebp64.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPEncodeBGRA")] [DllImport("x64\\imageprocessor.libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPEncodeBGRA")]
public static extern int WebPEncodeBGRA64(IntPtr rgb, int width, int height, int stride, float qualityFactor, out IntPtr output); private static extern int WebPEncodeBGRA64(IntPtr rgb, int width, int height, int stride, float qualityFactor, out IntPtr output);
/// <summary> /// <summary>
/// Frees the unmanaged memory. /// Frees the unmanaged memory.
@ -178,8 +273,8 @@ namespace ImageProcessor.Imaging.Formats
/// <returns> /// <returns>
/// 1 if success, otherwise error code returned in the case of (a) error(s). /// 1 if success, otherwise error code returned in the case of (a) error(s).
/// </returns> /// </returns>
[DllImport("libwebp32.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPFree")] [DllImport("x86\\imageprocessor.libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPFree")]
public static extern int WebPFree86(IntPtr pointer); private static extern int WebPFree86(IntPtr pointer);
/// <summary> /// <summary>
/// Frees the unmanaged memory. /// Frees the unmanaged memory.
@ -190,8 +285,8 @@ namespace ImageProcessor.Imaging.Formats
/// <returns> /// <returns>
/// 1 if success, otherwise error code returned in the case of (a) error(s). /// 1 if success, otherwise error code returned in the case of (a) error(s).
/// </returns> /// </returns>
[DllImport("libwebp64.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPFree")] [DllImport("x64\\imageprocessor.libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPFree")]
public static extern int WebPFree64(IntPtr pointer); private static extern int WebPFree64(IntPtr pointer);
#endregion #endregion
} }
} }

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

@ -31,12 +31,6 @@ namespace ImageProcessor.Imaging.Formats
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed. Suppression is OK here.")] [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed. Suppression is OK here.")]
public class WebPFormat : FormatBase public class WebPFormat : FormatBase
{ {
/// <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> /// <summary>
/// Gets the file headers. /// Gets the file headers.
/// </summary> /// </summary>
@ -190,19 +184,9 @@ namespace ImageProcessor.Imaging.Formats
int width; int width;
int height; int height;
if (Is64Bit) if (NativeMethods.WebPGetInfo(ptrData, dataSize, out width, out height) != 1)
{
if (NativeMethods.WebPGetInfo64(ptrData, dataSize, out width, out height) != 1)
{
throw new ImageFormatException("WebP image header is corrupted.");
}
}
else
{ {
if (NativeMethods.WebPGetInfo86(ptrData, dataSize, out width, out height) != 1) throw new ImageFormatException("WebP image header is corrupted.");
{
throw new ImageFormatException("WebP image header is corrupted.");
}
} }
try try
@ -215,17 +199,8 @@ namespace ImageProcessor.Imaging.Formats
int outputBufferSize = bitmapData.Stride * height; int outputBufferSize = bitmapData.Stride * height;
outputBuffer = Marshal.AllocHGlobal(outputBufferSize); outputBuffer = Marshal.AllocHGlobal(outputBufferSize);
// ReSharper disable once ConvertIfStatementToConditionalTernaryExpression // Uncompress the image
if (Is64Bit) outputBuffer = NativeMethods.WebPDecodeBGRAInto(ptrData, dataSize, outputBuffer, outputBufferSize, bitmapData.Stride);
{
// Uncompress the image
outputBuffer = NativeMethods.WebPDecodeBGRAInto64(ptrData, dataSize, outputBuffer, outputBufferSize, bitmapData.Stride);
}
else
{
// Uncompress the image
outputBuffer = NativeMethods.WebPDecodeBGRAInto86(ptrData, dataSize, outputBuffer, outputBufferSize, bitmapData.Stride);
}
// Write image to bitmap using Marshal // Write image to bitmap using Marshal
byte[] buffer = new byte[outputBufferSize]; byte[] buffer = new byte[outputBufferSize];
@ -272,19 +247,8 @@ namespace ImageProcessor.Imaging.Formats
try try
{ {
int size; // Attempt to lossy encode the image.
int size = NativeMethods.WebPEncodeBGRA(bmpData.Scan0, bitmap.Width, bitmap.Height, bmpData.Stride, quality, out unmanagedData);
// ReSharper disable once ConvertIfStatementToConditionalTernaryExpression
if (Is64Bit)
{
// Attempt to lossy encode the image.
size = NativeMethods.WebPEncodeBGRA64(bmpData.Scan0, bitmap.Width, bitmap.Height, bmpData.Stride, quality, out unmanagedData);
}
else
{
// Attempt to lossy encode the image.
size = NativeMethods.WebPEncodeBGRA86(bmpData.Scan0, bitmap.Width, bitmap.Height, bmpData.Stride, quality, out unmanagedData);
}
// Copy image compress data to output array // Copy image compress data to output array
webpData = new byte[size]; webpData = new byte[size];
@ -300,16 +264,8 @@ namespace ImageProcessor.Imaging.Formats
// Unlock the pixels // Unlock the pixels
bitmap.UnlockBits(bmpData); bitmap.UnlockBits(bmpData);
if (Is64Bit) // Free memory
{ NativeMethods.WebPFree(unmanagedData);
// Free memory
NativeMethods.WebPFree64(unmanagedData);
}
else
{
// Free memory
NativeMethods.WebPFree86(unmanagedData);
}
} }
return encoded; return encoded;

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

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

4
src/ImageProcessorConsole/Program.cs

@ -40,8 +40,8 @@ namespace ImageProcessorConsole
di.Create(); di.Create();
} }
IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".gif"); //IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".gif");
//IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".gif", ".webp", ".bmp", ".jpg", ".png"); IEnumerable<FileInfo> files = GetFilesByExtensions(di, ".gif", ".webp", ".bmp", ".jpg", ".png");
foreach (FileInfo fileInfo in files) foreach (FileInfo fileInfo in files)
{ {

2
src/ImageProcessorConsole/images/output/120430.gif.REMOVED.git-id

@ -1 +1 @@
6f3f997e323adb1fce142930d86338efacffc3fd 30ec5c05548fd350f9b7c699715848b9fbfb8ca9

2
src/ImageProcessorConsole/images/output/Tl4Yb.gif.REMOVED.git-id

@ -1 +1 @@
3ab082661fc5d88f88643c47409e196d66e26d4b fdc62fc2d056ab885eb9e8fd12b9155ee86d7c43

2
src/ImageProcessorConsole/images/output/nLpfllv.gif.REMOVED.git-id

@ -1 +1 @@
e2c2fbac64987ad26e19f5d2721fcaa60fee843d 23a1c81a2d1422076373796e0c47f5d968c56d0b

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

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5787cb5048c7e0eecccf1104594c3ad1aee6b142af5fe98435e4f9d49dc81f9b
size 22990

4
src/TestWebsites/NET45/Test_Website_NET45/Web.config

@ -43,8 +43,9 @@
</pages> </pages>
<httpModules> <httpModules>
<add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web"/> <add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web"/>
<add name="ImageProcessorNativeBinaryModule" type="ImageProcessor.Web.HttpModules.ImageProcessorNativeBinaryModule, ImageProcessor.Web"/>
</httpModules> </httpModules>
</system.web> </system.web>
<system.webServer> <system.webServer>
@ -63,6 +64,7 @@
</handlers> </handlers>
<modules> <modules>
<add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web"/> <add name="ImageProcessorModule" type="ImageProcessor.Web.HttpModules.ImageProcessingModule, ImageProcessor.Web"/>
<add name="ImageProcessorNativeBinaryModule" type="ImageProcessor.Web.HttpModules.ImageProcessorNativeBinaryModule, ImageProcessor.Web"/>
</modules> </modules>
</system.webServer> </system.webServer>
</configuration> </configuration>

Loading…
Cancel
Save