From 0c9397de3b6bb6c08ba6dfc26e33dc0ab52fc438 Mon Sep 17 00:00:00 2001 From: Nicholas Hayes <0xC0000054@users.noreply.github.com> Date: Mon, 3 Jul 2023 21:28:26 -0600 Subject: [PATCH] Add the plugin and libwebp versions to the save UI This makes it easier for users to determine what version of the plugin they have installed. The plugin version is also listed as part of the Paint.NET Diagnostics (in Settings > Diagnostics), but that is harder to find and use. --- src/IgnoredWords.dic | 1 + src/Interop/WebP_ARM64.cs | 4 ++++ src/Interop/WebP_x64.cs | 4 ++++ src/VersionInfo.cs | 43 +++++++++++++++++++++++++++++++++++++++ src/WebP/WebP.cpp | 8 ++++++++ src/WebP/WebP.h | 2 ++ src/WebPFileType.cs | 18 ++++++++++++++-- src/WebPNative.cs | 27 +++++++++++++++++++++++- 8 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 src/VersionInfo.cs diff --git a/src/IgnoredWords.dic b/src/IgnoredWords.dic index e3f6c09..4b1fa11 100644 --- a/src/IgnoredWords.dic +++ b/src/IgnoredWords.dic @@ -12,6 +12,7 @@ ifd interop jpeg kvp +libwebp metadata nq num diff --git a/src/Interop/WebP_ARM64.cs b/src/Interop/WebP_ARM64.cs index 47af083..f1aae94 100644 --- a/src/Interop/WebP_ARM64.cs +++ b/src/Interop/WebP_ARM64.cs @@ -18,6 +18,10 @@ namespace WebPFileType.Interop [System.Security.SuppressUnmanagedCodeSecurity] internal static unsafe partial class WebP_ARM64 { + [LibraryImport("WebP_ARM64.dll", EntryPoint = "GetLibWebPVersion")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(System.Runtime.CompilerServices.CallConvStdcall) })] + public static partial int GetLibWebPVersion(); + [LibraryImport("WebP_ARM64.dll", EntryPoint = "WebPGetImageInfo")] [UnmanagedCallConv(CallConvs = new Type[] { typeof(System.Runtime.CompilerServices.CallConvStdcall) })] public static partial VP8StatusCode WebPGetImageInfo(byte* data, UIntPtr dataSize, out ImageInfo info); diff --git a/src/Interop/WebP_x64.cs b/src/Interop/WebP_x64.cs index c3631ce..5a99cc5 100644 --- a/src/Interop/WebP_x64.cs +++ b/src/Interop/WebP_x64.cs @@ -18,6 +18,10 @@ namespace WebPFileType.Interop [System.Security.SuppressUnmanagedCodeSecurity] internal static unsafe partial class WebP_x64 { + [LibraryImport("WebP_x64.dll", EntryPoint = "GetLibWebPVersion")] + [UnmanagedCallConv(CallConvs = new Type[] { typeof(System.Runtime.CompilerServices.CallConvStdcall) })] + public static partial int GetLibWebPVersion(); + [LibraryImport("WebP_x64.dll", EntryPoint = "WebPGetImageInfo")] [UnmanagedCallConv(CallConvs = new Type[] { typeof(System.Runtime.CompilerServices.CallConvStdcall) })] public static partial VP8StatusCode WebPGetImageInfo(byte* data, UIntPtr dataSize, out ImageInfo info); diff --git a/src/VersionInfo.cs b/src/VersionInfo.cs new file mode 100644 index 0000000..6dc68ea --- /dev/null +++ b/src/VersionInfo.cs @@ -0,0 +1,43 @@ +//////////////////////////////////////////////////////////////////////// +// +// This file is part of pdn-webp, a FileType plugin for Paint.NET +// that loads and saves WebP images. +// +// Copyright (c) 2011-2023 Nicholas Hayes +// +// This file is licensed under the MIT License. +// See LICENSE.txt for complete licensing and attribution information. +// +//////////////////////////////////////////////////////////////////////// + +using System; +using System.Diagnostics; + +namespace WebPFileType +{ + internal static class VersionInfo + { + private static readonly Lazy libwebpVersion = new(GetLibWebPVersion); + private static readonly Lazy pluginVersion = new(GetPluginVersion); + + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + public static string LibWebPVersion => libwebpVersion.Value; + + [DebuggerBrowsable(DebuggerBrowsableState.Never)] + public static string PluginVersion => pluginVersion.Value; + + private static string GetLibWebPVersion() + { + int libwebpVersion = WebPNative.GetLibWebPVersion(); + + int major = (libwebpVersion >> 16) & 0xff; + int minor = (libwebpVersion >> 8) & 0xff; + int revision = libwebpVersion & 0xff; + + return $"{major}.{minor}.{revision}"; + } + + private static string GetPluginVersion() + => typeof(VersionInfo).Assembly.GetName().Version.ToString(); + } +} diff --git a/src/WebP/WebP.cpp b/src/WebP/WebP.cpp index fe3fc02..35245cc 100644 --- a/src/WebP/WebP.cpp +++ b/src/WebP/WebP.cpp @@ -14,6 +14,14 @@ #include "WebP.h" #include "scoped.h" +DLLEXPORT int __stdcall GetLibWebPVersion() +{ + // Each libwebp API set has its own method to get the version number. + // All of the version numbers should be identical for a specific libwebp release, + // so we use the decoder version number; + return WebPGetDecoderVersion(); +} + int __stdcall WebPGetImageInfo(const uint8_t* data, size_t dataSize, ImageInfo* info) { WebPBitstreamFeatures features; diff --git a/src/WebP/WebP.h b/src/WebP/WebP.h index 4f03dd1..8dc6bfd 100644 --- a/src/WebP/WebP.h +++ b/src/WebP/WebP.h @@ -73,6 +73,8 @@ typedef struct ImageInfo bool hasAnimation; }ImageInfo; +DLLEXPORT int __stdcall GetLibWebPVersion(); + DLLEXPORT int __stdcall WebPGetImageInfo(const uint8_t* data, size_t dataSize, ImageInfo* info); DLLEXPORT bool __stdcall WebPGetImageMetadata(const uint8_t* data, size_t dataSize, SetDecoderMetadataFn setMetadata); diff --git a/src/WebPFileType.cs b/src/WebPFileType.cs index 917c232..f3bc3d8 100644 --- a/src/WebPFileType.cs +++ b/src/WebPFileType.cs @@ -33,7 +33,9 @@ private enum PropertyNames KeepMetadata, // Obsolete, but retained to keep the value from being reused for a different property. ForumLink, GitHubLink, - Lossless + Lossless, + PluginVersion, + LibWebPVersion } private readonly IWebPStringResourceManager strings; @@ -201,7 +203,9 @@ public override PropertyCollection OnCreateSavePropertyCollection() new Int32Property(PropertyNames.Quality, 95, 0, 100, false), new BooleanProperty(PropertyNames.Lossless, false), new UriProperty(PropertyNames.ForumLink, new Uri("https://forums.getpaint.net/topic/21773-webp-filetype/")), - new UriProperty(PropertyNames.GitHubLink, new Uri("https://github.com/0xC0000054/pdn-webp")) + new UriProperty(PropertyNames.GitHubLink, new Uri("https://github.com/0xC0000054/pdn-webp")), + new StringProperty(PropertyNames.PluginVersion), + new StringProperty(PropertyNames.LibWebPVersion), }; List rules = new() @@ -240,6 +244,16 @@ public override ControlInfo OnCreateSaveConfigUI(PropertyCollection props) githubLinkPCI.ControlProperties[ControlInfoPropertyNames.DisplayName].Value = string.Empty; githubLinkPCI.ControlProperties[ControlInfoPropertyNames.Description].Value = "GitHub"; // GitHub is a brand name that should not be localized. + PropertyControlInfo pluginVersionPCI = info.FindControlForPropertyName(PropertyNames.PluginVersion); + pluginVersionPCI.ControlType.Value = PropertyControlType.Label; + pluginVersionPCI.ControlProperties[ControlInfoPropertyNames.DisplayName].Value = string.Empty; + pluginVersionPCI.ControlProperties[ControlInfoPropertyNames.Description].Value = "WebPFileType v" + VersionInfo.PluginVersion; + + PropertyControlInfo libwebpVersionPCI = info.FindControlForPropertyName(PropertyNames.LibWebPVersion); + libwebpVersionPCI.ControlType.Value = PropertyControlType.Label; + libwebpVersionPCI.ControlProperties[ControlInfoPropertyNames.DisplayName].Value = string.Empty; + libwebpVersionPCI.ControlProperties[ControlInfoPropertyNames.Description].Value = "libwebp v" + VersionInfo.LibWebPVersion; + return info; } diff --git a/src/WebPNative.cs b/src/WebPNative.cs index bdb2cf9..58164a1 100644 --- a/src/WebPNative.cs +++ b/src/WebPNative.cs @@ -14,7 +14,6 @@ using System; using System.Globalization; using System.IO; -using System.Runtime.ExceptionServices; using System.Runtime.InteropServices; using WebPFileType.Interop; using WebPFileType.Properties; @@ -25,6 +24,32 @@ internal static class WebPNative { internal const int WebPMaxDimension = 16383; + /// + /// Gets the libwebp version number. + /// + /// + /// The libwebp version number. + /// + internal static int GetLibWebPVersion() + { + int version; + + if (RuntimeInformation.ProcessArchitecture == Architecture.X64) + { + version = WebP_x64.GetLibWebPVersion(); + } + else if (RuntimeInformation.ProcessArchitecture == Architecture.Arm64) + { + version = WebP_ARM64.GetLibWebPVersion(); + } + else + { + throw new PlatformNotSupportedException(); + } + + return version; + } + /// /// Gets the WebP image information. ///