First try

This commit is contained in:
Karou 2025-12-26 02:31:50 -05:00
parent c00363badf
commit 44c0b7ebdd
4 changed files with 63 additions and 3 deletions

View file

@ -59,7 +59,7 @@ internal sealed partial class TextureManager
/// <param name="textureWrap">The texture.</param>
/// <param name="ownerPlugin">The plugin.</param>
/// <returns>Same <paramref name="textureWrap"/>.</returns>
public unsafe IDalamudTextureWrap Blame(IDalamudTextureWrap textureWrap, LocalPlugin? ownerPlugin)
public unsafe IDalamudTextureWrap Blame(IDalamudTextureWrap? textureWrap, LocalPlugin? ownerPlugin)
{
if (!this.dalamudConfiguration.UseTexturePluginTracking)
return textureWrap;

View file

@ -1,5 +1,7 @@
using System.Drawing;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
@ -17,13 +19,21 @@ using Dalamud.Plugin.Services;
using Dalamud.Storage.Assets;
using Dalamud.Utility;
using Dalamud.Utility.TerraFxCom;
using Lumina.Data;
using Lumina.Data.Files;
using TerraFX.Interop.DirectX;
using TerraFX.Interop.Windows;
using static TerraFX.Interop.Windows.COINIT;
using static TerraFX.Interop.Windows.SIIGBF;
using static TerraFX.Interop.Windows.Windows;
using BitmapData = System.Drawing.Imaging.BitmapData;
using HBITMAP = TerraFX.Interop.Windows.HBITMAP;
using ImageLockMode = System.Drawing.Imaging.ImageLockMode;
using IShellItemImageFactory = TerraFX.Interop.Windows.IShellItemImageFactory;
using SIZE = TerraFX.Interop.Windows.SIZE;
namespace Dalamud.Interface.Textures.Internal;
/// <summary>Service responsible for loading and disposing ImGui texture wraps.</summary>
@ -303,6 +313,42 @@ internal sealed partial class TextureManager
return (supported & required) == required;
}
/// <inheritdoc/>
public unsafe IDalamudTextureWrap? TryGetFileThumbnail(string path)
{
const int size = 256;
HRESULT hr = CoInitializeEx(null, (uint)(COINIT_DISABLE_OLE1DDE | COINIT_MULTITHREADED));
if (hr.FAILED)
return null;
IShellItemImageFactory* imageFact;
fixed (char* pstr = path)
{
hr = SHCreateItemFromParsingName(pstr, null, __uuidof<IShellItemImageFactory>(), (void**)&imageFact);
}
if (hr.FAILED)
return null;
HBITMAP hbmp;
imageFact->GetImage(new SIZE(cx: size, cy: size), (int)SIIGBF_BIGGERSIZEOK, &hbmp);
var image = Image.FromHbitmap(hbmp);
BitmapData bd = image.LockBits(new(Point.Empty, image.Size), ImageLockMode.ReadOnly, image.PixelFormat);
var rowSize = bd.Stride < 0 ? -bd.Stride : bd.Stride;
var pixels = new byte[bd.Height * rowSize];
var iptr = bd.Scan0;
for (int y = 0; y < bd.Height; y++)
{
Marshal.Copy(IntPtr.Add(iptr, y * bd.Stride),
pixels, y * rowSize,
rowSize);
}
image.UnlockBits(bd);
return this.CreateFromRaw(new RawImageSpecification(bd.Width, bd.Height, (int)DXGI_FORMAT.DXGI_FORMAT_B8G8R8A8_UNORM), pixels.AsSpan());
}
/// <inheritdoc cref="ITextureProvider.CreateFromRaw"/>
internal unsafe IDalamudTextureWrap NoThrottleCreateFromRaw(
RawImageSpecification specs,

View file

@ -454,6 +454,15 @@ internal sealed class TextureManagerPluginScoped
await manager.CopyToClipboardAsync(wrap, preferredFileNameWithoutExtension, leaveWrapOpen, cancellationToken);
}
/// <inheritdoc/>
public IDalamudTextureWrap? TryGetFileThumbnail(string path)
{
var manager = this.ManagerOrThrow;
var textureWrap = manager.TryGetFileThumbnail(path);
manager.Blame(textureWrap, this.plugin);
return textureWrap;
}
private void ResultOnInterceptTexDataLoad(string path, ref string? replacementPath) =>
this.InterceptTexDataLoad?.Invoke(path, ref replacementPath);
}

View file

@ -330,4 +330,9 @@ public interface ITextureProvider : IDalamudService
/// <c>((delegate* unmanaged&lt;nint, void&gt;)(*(nint**)ptr)[3](ptr)</c>.</para>
/// </remarks>
nint ConvertToKernelTexture(IDalamudTextureWrap wrap, bool leaveWrapOpen = false);
/// <summary>Tries to get a files thumbnail from the Win32 API</summary>
/// <param name="filePath">Path to file you want to preview.</param>
/// <returns>A <see cref="IDalamudTextureWrap"/> TextureWrap or null.</returns>
IDalamudTextureWrap? TryGetFileThumbnail(string filePath);
}