diff --git a/build/NuSpecs/ImageProcessor.nuspec b/build/NuSpecs/ImageProcessor.nuspec index 85b661b2e..30e157086 100644 --- a/build/NuSpecs/ImageProcessor.nuspec +++ b/build/NuSpecs/ImageProcessor.nuspec @@ -25,6 +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 new file mode 100644 index 000000000..6922fa306 --- /dev/null +++ b/build/content/ImageProcessor/imageprocessor.targets @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/ImageProcessor/ImageProcessor.csproj b/src/ImageProcessor/ImageProcessor.csproj index 68702ed09..802dadb56 100644 --- a/src/ImageProcessor/ImageProcessor.csproj +++ b/src/ImageProcessor/ImageProcessor.csproj @@ -130,7 +130,10 @@ - + + PreserveNewest + + PreserveNewest diff --git a/src/ImageProcessor/Imaging/Formats/NativeMethods.cs b/src/ImageProcessor/Imaging/Formats/NativeMethods.cs index eb9062e91..059c5259a 100644 --- a/src/ImageProcessor/Imaging/Formats/NativeMethods.cs +++ b/src/ImageProcessor/Imaging/Formats/NativeMethods.cs @@ -37,8 +37,53 @@ namespace ImageProcessor.Imaging.Formats /// /// 1 if success, otherwise error code returned in the case of (a) formatting error(s). /// - [DllImport("libwebp.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int WebPGetInfo(IntPtr data, uint dataSize, out int width, out int height); + [DllImport("x86\\libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPGetInfo")] + public static extern int WebPGetInfo86(IntPtr data, uint dataSize, out int width, out int height); + + /// + /// Validate the WebP image header and retrieve the image height and width. Pointers *width and *height can be passed NULL if deemed irrelevant + /// + /// + /// Pointer to WebP image data + /// + /// + /// This is the size of the memory block pointed to by data containing the image data + /// + /// + /// The width range is limited currently from 1 to 16383 + /// + /// + /// The height range is limited currently from 1 to 16383 + /// + /// + /// 1 if success, otherwise error code returned in the case of (a) formatting error(s). + /// + [DllImport("x64\\libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPGetInfo")] + public static extern int WebPGetInfo64(IntPtr data, uint dataSize, out int width, out int height); + + /// + /// Decode WEBP image pointed to by *data and returns BGR samples into a pre-allocated buffer + /// + /// + /// Pointer to WebP image data + /// + /// + /// This is the size of the memory block pointed to by data containing the image data + /// + /// + /// Pointer to decoded WebP image + /// + /// + /// Size of allocated buffer + /// + /// + /// Specifies the distance between scan-lines + /// + /// + /// output_buffer if function succeeds; NULL otherwise + /// + [DllImport("x86\\libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPDecodeBGRAInto")] + public static extern IntPtr WebPDecodeBGRAInto86(IntPtr data, uint dataSize, IntPtr outputBuffer, int outputBufferSize, int outputStride); /// /// Decode WEBP image pointed to by *data and returns BGR samples into a pre-allocated buffer @@ -61,8 +106,35 @@ namespace ImageProcessor.Imaging.Formats /// /// output_buffer if function succeeds; NULL otherwise /// - [DllImport("libwebp.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern IntPtr WebPDecodeBGRAInto(IntPtr data, uint dataSize, IntPtr outputBuffer, int outputBufferSize, int outputStride); + [DllImport("x64\\libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPDecodeBGRAInto")] + public static extern IntPtr WebPDecodeBGRAInto64(IntPtr data, uint dataSize, IntPtr outputBuffer, int outputBufferSize, int outputStride); + + /// + /// Lossy encoding images pointed to by *data in WebP format + /// + /// + /// Pointer to RGB image data + /// + /// + /// The width range is limited currently from 1 to 16383 + /// + /// + /// The height range is limited currently from 1 to 16383 + /// + /// + /// The stride. + /// + /// + /// Ranges from 0 (lower quality) to 100 (highest quality). Controls the loss and quality during compression + /// + /// + /// output_buffer with WebP image + /// + /// + /// Size of WebP Image + /// + [DllImport("x86\\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); /// /// Lossy encoding images pointed to by *data in WebP format @@ -88,8 +160,20 @@ namespace ImageProcessor.Imaging.Formats /// /// Size of WebP Image /// - [DllImport("libwebp.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int WebPEncodeBGRA(IntPtr rgb, int width, int height, int stride, float qualityFactor, out IntPtr output); + [DllImport("x64\\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); + + /// + /// Frees the unmanaged memory. + /// + /// + /// The pointer. + /// + /// + /// 1 if success, otherwise error code returned in the case of (a) error(s). + /// + [DllImport("x86\\libwebp.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "WebPFree")] + public static extern int WebPFree86(IntPtr pointer); /// /// Frees the unmanaged memory. @@ -100,8 +184,8 @@ namespace ImageProcessor.Imaging.Formats /// /// 1 if success, otherwise error code returned in the case of (a) error(s). /// - [DllImport("libwebp.dll", CallingConvention = CallingConvention.Cdecl)] - public static extern int WebPFree(IntPtr pointer); + [DllImport("x64\\libwebp.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 d8c9bbf33..1617d37be 100644 --- a/src/ImageProcessor/Imaging/Formats/WebPFormat.cs +++ b/src/ImageProcessor/Imaging/Formats/WebPFormat.cs @@ -31,6 +31,12 @@ namespace ImageProcessor.Imaging.Formats [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed. Suppression is OK here.")] public class WebPFormat : FormatBase { + /// + /// Whether the process is running in 63bit 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; + /// /// Gets the file headers. /// @@ -184,9 +190,19 @@ namespace ImageProcessor.Imaging.Formats int width; int height; - if (NativeMethods.WebPGetInfo(ptrData, dataSize, out width, out height) != 1) + if (Is64Bit) + { + if (NativeMethods.WebPGetInfo64(ptrData, dataSize, out width, out height) != 1) + { + throw new ImageFormatException("WebP image header is corrupted."); + } + } + else { - throw new ImageFormatException("WebP image header is corrupted."); + if (NativeMethods.WebPGetInfo86(ptrData, dataSize, out width, out height) != 1) + { + throw new ImageFormatException("WebP image header is corrupted."); + } } try @@ -199,8 +215,17 @@ namespace ImageProcessor.Imaging.Formats int outputBufferSize = bitmapData.Stride * height; outputBuffer = Marshal.AllocHGlobal(outputBufferSize); - // Uncompress the image - outputBuffer = NativeMethods.WebPDecodeBGRAInto(ptrData, dataSize, outputBuffer, outputBufferSize, bitmapData.Stride); + // ReSharper disable once ConvertIfStatementToConditionalTernaryExpression + if (Is64Bit) + { + // 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); + } if (bitmapData.Scan0 != outputBuffer) { @@ -252,8 +277,19 @@ namespace ImageProcessor.Imaging.Formats try { - // Attempt to lossy encode the image. - int size = NativeMethods.WebPEncodeBGRA(bmpData.Scan0, bitmap.Width, bitmap.Height, bmpData.Stride, quality, out unmanagedData); + int size; + + // 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 webpData = new byte[size]; @@ -269,8 +305,16 @@ namespace ImageProcessor.Imaging.Formats // Unlock the pixels bitmap.UnlockBits(bmpData); - // Free memory - NativeMethods.WebPFree(unmanagedData); + if (Is64Bit) + { + // Free memory + NativeMethods.WebPFree64(unmanagedData); + } + else + { + // Free memory + NativeMethods.WebPFree86(unmanagedData); + } } return encoded; diff --git a/src/ImageProcessor/libwebp.dll.REMOVED.git-id b/src/ImageProcessor/libwebp.dll.REMOVED.git-id deleted file mode 100644 index e05b4f051..000000000 --- a/src/ImageProcessor/libwebp.dll.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -ed0333da619a813e8337d77ba7ee206ea5f20a51 \ No newline at end of file diff --git a/src/ImageProcessor/x64/libwebp.dll.REMOVED.git-id b/src/ImageProcessor/x64/libwebp.dll.REMOVED.git-id new file mode 100644 index 000000000..35684c541 --- /dev/null +++ b/src/ImageProcessor/x64/libwebp.dll.REMOVED.git-id @@ -0,0 +1 @@ +dcadab1b5b86469758707bff22558b33e5c51552 \ No newline at end of file diff --git a/src/ImageProcessor/x86/libwebp.dll.REMOVED.git-id b/src/ImageProcessor/x86/libwebp.dll.REMOVED.git-id new file mode 100644 index 000000000..129db9826 --- /dev/null +++ b/src/ImageProcessor/x86/libwebp.dll.REMOVED.git-id @@ -0,0 +1 @@ +ad47008dd1e64ea220bc745e28f568277434d661 \ No newline at end of file diff --git a/src/ImageProcessorConsole/Program.cs b/src/ImageProcessorConsole/Program.cs index 20e92e803..64053c5ed 100644 --- a/src/ImageProcessorConsole/Program.cs +++ b/src/ImageProcessorConsole/Program.cs @@ -52,7 +52,7 @@ namespace ImageProcessorConsole // ImageProcessor using (MemoryStream inStream = new MemoryStream(photoBytes)) { - using (ImageFactory imageFactory = new ImageFactory(true)) + using (ImageFactory imageFactory = new ImageFactory()) { Size size = new Size(200, 200); diff --git a/src/ImageProcessorConsole/images/output/120430.gif.REMOVED.git-id b/src/ImageProcessorConsole/images/output/120430.gif.REMOVED.git-id deleted file mode 100644 index 71ce555c1..000000000 --- a/src/ImageProcessorConsole/images/output/120430.gif.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -30ec5c05548fd350f9b7c699715848b9fbfb8ca9 \ No newline at end of file diff --git a/src/ImageProcessorConsole/images/output/4.sm.webp b/src/ImageProcessorConsole/images/output/4.sm.webp deleted file mode 100644 index 90a630864..000000000 Binary files a/src/ImageProcessorConsole/images/output/4.sm.webp and /dev/null differ diff --git a/src/ImageProcessorConsole/images/output/Tl4Yb.gif.REMOVED.git-id b/src/ImageProcessorConsole/images/output/Tl4Yb.gif.REMOVED.git-id deleted file mode 100644 index 6515d65a0..000000000 --- a/src/ImageProcessorConsole/images/output/Tl4Yb.gif.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -fdc62fc2d056ab885eb9e8fd12b9155ee86d7c43 \ No newline at end of file diff --git a/src/ImageProcessorConsole/images/output/circle.webp b/src/ImageProcessorConsole/images/output/circle.webp deleted file mode 100644 index ef0281087..000000000 Binary files a/src/ImageProcessorConsole/images/output/circle.webp and /dev/null differ diff --git a/src/ImageProcessorConsole/images/output/nLpfllv.gif.REMOVED.git-id b/src/ImageProcessorConsole/images/output/nLpfllv.gif.REMOVED.git-id deleted file mode 100644 index 4487aede0..000000000 --- a/src/ImageProcessorConsole/images/output/nLpfllv.gif.REMOVED.git-id +++ /dev/null @@ -1 +0,0 @@ -23a1c81a2d1422076373796e0c47f5d968c56d0b \ No newline at end of file diff --git a/src/ImageProcessorConsole/images/output/rotate.webp b/src/ImageProcessorConsole/images/output/rotate.webp index ca786888a..3cc93f149 100644 Binary files a/src/ImageProcessorConsole/images/output/rotate.webp and b/src/ImageProcessorConsole/images/output/rotate.webp differ diff --git a/src/ImageProcessorConsole/images/output/test.webp b/src/ImageProcessorConsole/images/output/test.webp deleted file mode 100644 index 549fb9c6b..000000000 Binary files a/src/ImageProcessorConsole/images/output/test.webp and /dev/null differ