Added a routine to get the WIC supported extensions automatically.

This commit is contained in:
Robin Krom 2022-02-19 00:37:36 +01:00
commit baad75aacc
No known key found for this signature in database
GPG key ID: BCC01364F1371490
7 changed files with 70 additions and 17 deletions

View file

@ -523,9 +523,9 @@ EndSelection:<<<<<<<4
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>(); var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
var supportedExtensions = fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList(); var supportedExtensions = fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList();
foreach (var fileData in IterateClipboardContent(dataObject)) foreach (var (stream, filename) in IterateClipboardContent(dataObject))
{ {
var extension = Path.GetExtension(fileData.filename)?.ToLowerInvariant(); var extension = Path.GetExtension(filename)?.ToLowerInvariant();
if (!supportedExtensions.Contains(extension)) if (!supportedExtensions.Contains(extension))
{ {
continue; continue;
@ -535,7 +535,7 @@ EndSelection:<<<<<<<4
try try
{ {
if (!fileFormatHandlers.TryLoadFromStream(fileData.stream, extension, out bitmap)) if (!fileFormatHandlers.TryLoadFromStream(stream, extension, out bitmap))
{ {
continue; continue;
} }
@ -548,7 +548,7 @@ EndSelection:<<<<<<<4
} }
finally finally
{ {
fileData.stream?.Dispose(); stream?.Dispose();
} }
// If we get here, there is an image // If we get here, there is an image
yield return bitmap; yield return bitmap;
@ -601,9 +601,9 @@ EndSelection:<<<<<<<4
var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>(); var fileFormatHandlers = SimpleServiceProvider.Current.GetAllInstances<IFileFormatHandler>();
var supportedExtensions = fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList(); var supportedExtensions = fileFormatHandlers.ExtensionsFor(FileFormatHandlerActions.LoadDrawableFromStream).ToList();
foreach (var fileData in IterateClipboardContent(dataObject)) foreach (var (stream, filename) in IterateClipboardContent(dataObject))
{ {
var extension = Path.GetExtension(fileData.filename)?.ToLowerInvariant(); var extension = Path.GetExtension(filename)?.ToLowerInvariant();
if (!supportedExtensions.Contains(extension)) if (!supportedExtensions.Contains(extension))
{ {
continue; continue;
@ -612,7 +612,7 @@ EndSelection:<<<<<<<4
IEnumerable<IDrawableContainer> drawableContainers; IEnumerable<IDrawableContainer> drawableContainers;
try try
{ {
drawableContainers = fileFormatHandlers.LoadDrawablesFromStream(fileData.stream, extension); drawableContainers = fileFormatHandlers.LoadDrawablesFromStream(stream, extension);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -621,7 +621,7 @@ EndSelection:<<<<<<<4
} }
finally finally
{ {
fileData.stream?.Dispose(); stream?.Dispose();
} }
// If we get here, there is an image // If we get here, there is an image
foreach (var container in drawableContainers) foreach (var container in drawableContainers)

View file

@ -58,7 +58,7 @@ namespace Greenshot.Base.Core.FileFormatHandlers
/// <returns></returns> /// <returns></returns>
public static IEnumerable<string> ExtensionsFor(this IEnumerable<IFileFormatHandler> fileFormatHandlers, FileFormatHandlerActions fileFormatHandlerAction) public static IEnumerable<string> ExtensionsFor(this IEnumerable<IFileFormatHandler> fileFormatHandlers, FileFormatHandlerActions fileFormatHandlerAction)
{ {
return fileFormatHandlers.Where(ffh => ffh.SupportedExtensions.ContainsKey(fileFormatHandlerAction)).SelectMany(ffh => ffh.SupportedExtensions[fileFormatHandlerAction]).Distinct(); return fileFormatHandlers.Where(ffh => ffh.SupportedExtensions.ContainsKey(fileFormatHandlerAction)).SelectMany(ffh => ffh.SupportedExtensions[fileFormatHandlerAction]).Distinct().OrderBy(e => e);
} }
/// <summary> /// <summary>

View file

@ -26,7 +26,6 @@ using System.Drawing.Imaging;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using Greenshot.Base.IniFile;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
using Greenshot.Base.Interfaces.Plugin; using Greenshot.Base.Interfaces.Plugin;
using log4net; using log4net;
@ -40,7 +39,6 @@ namespace Greenshot.Editor.FileFormatHandlers
{ {
private static readonly ILog Log = LogManager.GetLogger(typeof(DefaultFileFormatHandler)); private static readonly ILog Log = LogManager.GetLogger(typeof(DefaultFileFormatHandler));
private readonly IReadOnlyCollection<string> _ourExtensions = new[] { ".png", ".bmp", ".gif", ".jpg", ".jpeg", ".tiff", ".tif" }; private readonly IReadOnlyCollection<string> _ourExtensions = new[] { ".png", ".bmp", ".gif", ".jpg", ".jpeg", ".tiff", ".tif" };
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
public DefaultFileFormatHandler() public DefaultFileFormatHandler()
{ {
SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions; SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = _ourExtensions;

View file

@ -21,14 +21,15 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Linq;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using Greenshot.Base.Interfaces; using Greenshot.Base.Interfaces;
using Greenshot.Base.Core; using Greenshot.Base.Core;
using Greenshot.Base.Interfaces.Plugin; using Greenshot.Base.Interfaces.Plugin;
using log4net; using log4net;
using Microsoft.Win32;
namespace Greenshot.Editor.FileFormatHandlers namespace Greenshot.Editor.FileFormatHandlers
{ {
@ -38,16 +39,67 @@ namespace Greenshot.Editor.FileFormatHandlers
public class WpfFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler public class WpfFileFormatHandler : AbstractFileFormatHandler, IFileFormatHandler
{ {
private static readonly ILog Log = LogManager.GetLogger(typeof(WpfFileFormatHandler)); private static readonly ILog Log = LogManager.GetLogger(typeof(WpfFileFormatHandler));
private IReadOnlyCollection<string> LoadFromStreamExtensions { get; } = new []{ ".jxr", ".wdp", ".wmp", ".heic", ".heif" }; private const string HeifDecoder = "{E9A4A80A-44FE-4DE4-8971-7150B10A5199}";
private const string WicDecoderCategory = "{7ED96837-96F0-4812-B211-F13C24117ED3}";
private IReadOnlyCollection<string> LoadFromStreamExtensions { get; } = new []{ ".jxr", ".dds", ".hdp", ".wdp", ".wmp"};
private IReadOnlyCollection<string> SaveToStreamExtensions { get; } = new[] { ".jxr" }; private IReadOnlyCollection<string> SaveToStreamExtensions { get; } = new[] { ".jxr" };
public WpfFileFormatHandler() public WpfFileFormatHandler()
{ {
LoadFromStreamExtensions = LoadFromStreamExtensions.ToList().Concat(RetrieveSupportedExtensions()).OrderBy(e => e).Distinct().ToArray();
SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = LoadFromStreamExtensions; SupportedExtensions[FileFormatHandlerActions.LoadDrawableFromStream] = LoadFromStreamExtensions;
SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = LoadFromStreamExtensions; SupportedExtensions[FileFormatHandlerActions.LoadFromStream] = LoadFromStreamExtensions;
SupportedExtensions[FileFormatHandlerActions.SaveToStream] = SaveToStreamExtensions; SupportedExtensions[FileFormatHandlerActions.SaveToStream] = SaveToStreamExtensions;
} }
/// <summary>
/// Detect all the formats WIC supports
/// </summary>
/// <returns>IEnumerable{string}</returns>
private IEnumerable<string> RetrieveSupportedExtensions()
{
string baseKeyPath;
if (Environment.Is64BitOperatingSystem && !Environment.Is64BitProcess)
{
baseKeyPath = "Wow6432Node\\CLSID";
}
else
{
baseKeyPath = "CLSID";
}
using RegistryKey baseKey = Registry.ClassesRoot.OpenSubKey(baseKeyPath, false);
if (baseKey == null) yield break;
var wicDecoderCategoryPath = Path.Combine(baseKeyPath, WicDecoderCategory, "instance");
using RegistryKey categoryKey = Registry.ClassesRoot.OpenSubKey(wicDecoderCategoryPath, false);
if (categoryKey == null)
{
yield break;
}
foreach (var codecGuid in categoryKey.GetSubKeyNames())
{
// Read the properties of the single registered decoder
using var codecKey = baseKey.OpenSubKey(codecGuid);
if (codecKey == null) continue;
var fileExtensions = Convert.ToString(codecKey.GetValue("FileExtensions", "")).ToLowerInvariant();
foreach (var fileExtension in fileExtensions.Split(','))
{
yield return fileExtension;
}
}
var heifDecoderPath = Path.Combine(baseKeyPath, HeifDecoder);
using RegistryKey heifKey = Registry.ClassesRoot.OpenSubKey(heifDecoderPath, false);
if (heifKey == null) yield break;
yield return ".heic";
yield return ".heif";
}
/// <inheritdoc /> /// <inheritdoc />
public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null) public override bool TrySaveToStream(Bitmap bitmap, Stream destination, string extension, ISurface surface = null, SurfaceOutputSettings surfaceOutputSettings = null)
{ {

View file

@ -181,6 +181,9 @@ namespace Greenshot.Editor.Forms
UpdateUi(); UpdateUi();
// Use best fit
ZoomBestFitMenuItemClick(this, EventArgs.Empty);
// Workaround: As the cursor is (mostly) selected on the surface a funny artifact is visible, this fixes it. // Workaround: As the cursor is (mostly) selected on the surface a funny artifact is visible, this fixes it.
HideToolstripItems(); HideToolstripItems();
} }

View file

@ -44,6 +44,7 @@ using Greenshot.Base.Interfaces.Plugin;
using Greenshot.Base.UnmanagedHelpers; using Greenshot.Base.UnmanagedHelpers;
using Greenshot.Configuration; using Greenshot.Configuration;
using Greenshot.Destinations; using Greenshot.Destinations;
using Greenshot.Editor;
using Greenshot.Editor.Destinations; using Greenshot.Editor.Destinations;
using Greenshot.Editor.Drawing; using Greenshot.Editor.Drawing;
using Greenshot.Editor.Forms; using Greenshot.Editor.Forms;
@ -163,7 +164,7 @@ namespace Greenshot.Forms
if (argument.ToLower().Equals("/exit")) if (argument.ToLower().Equals("/exit"))
{ {
// unregister application on uninstall (allow uninstall) // un-register application on uninstall (allow uninstall)
try try
{ {
LOG.Info("Sending all instances the exit command."); LOG.Info("Sending all instances the exit command.");
@ -388,6 +389,8 @@ namespace Greenshot.Forms
_instance = this; _instance = this;
EditorInitialize.Initialize();
// Factory for surface objects // Factory for surface objects
ISurface SurfaceFactory() => new Surface(); ISurface SurfaceFactory() => new Surface();

View file

@ -20,11 +20,9 @@
*/ */
using System; using System;
using System.Drawing.Imaging;
using System.Globalization; using System.Globalization;
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using Greenshot.Editor;
using Greenshot.Forms; using Greenshot.Forms;
namespace Greenshot namespace Greenshot
@ -67,7 +65,6 @@ namespace Greenshot
CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture; CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture; CultureInfo.DefaultThreadCurrentUICulture = CultureInfo.InvariantCulture;
EditorInitialize.Initialize();
MainForm.Start(args); MainForm.Start(args);
} }
} }