Jump to content

Why isn't my file type plugin showing a preview thumbnail in Explorer?


aybe
 Share

Recommended Posts

Just noticed that the plugin I quickly wrote to open TIM files does not show a thumbnail preview in Windows Explorer, in the following screenshot both PNG and TIM are associated to be opened by the software, PNG shows a preview thumbnail but TIM doesn't:

 

explorer_4mUH0b50K5.thumb.png.9f74f8d6424aef01df3655d0f074a781.png

 

Is there something I'm missing in order to get thumbnail previews in Explorer ?

 

This is the current code:

 

using System.IO;
using System.Text;
using PaintDotNet;
using PaintDotNet.PropertySystem;

namespace TimFileType;
#pragma warning disable CA1416 // Validate platform compatibility

public sealed class TimFileTypeFactory : IFileTypeFactory2
{
    public FileType[] GetFileTypeInstances(IFileTypeHost host)
    {
        return new FileType[] { new TimFileTypeClass(host.Services) };
    }
}

[PluginSupportInfo(typeof(PluginSupportInfo))]
public class TimFileTypeClass : PropertyBasedFileType
{
    public TimFileTypeClass(IServiceProvider serviceProvider)
        : base("TIM: Screen Image Data", new FileTypeOptions { LoadExtensions = new[] { ".tim" } })
    {
        ServiceProvider = serviceProvider;
    }

    private IServiceProvider ServiceProvider { get; }

    protected override unsafe Document OnLoad(Stream input)
    {
        using var reader = new BinaryReader(input, Encoding.Default, true);

        reader.ReadByte();
        reader.ReadByte();
        reader.ReadInt16();

        var flags   = reader.ReadInt32();
        var format  = flags & 0b111;
        var palette = (flags & 0b1000) != 0;

        if (palette)
        {
            var length = reader.ReadInt32();
            reader.BaseStream.Position += length - 4;
        }

        // 24-bit only for now

        var pixelDataSize = reader.ReadInt32();
        var frameBufferX  = reader.ReadInt16();
        var frameBufferY  = reader.ReadInt16();
        var pixelWidth    = reader.ReadInt16();
        var pixelHeight   = reader.ReadInt16();
        var pixelData     = reader.ReadBytes(pixelDataSize - 12);

        pixelWidth = (short)(pixelWidth * 2 / 3);
        var layer = Layer.CreateBackgroundLayer(pixelWidth, pixelHeight);

        var pointer = layer.Surface.GetRowPointer(0);

        for (var i = 0; i < pixelWidth * pixelHeight; i ++)
        {
            pointer->R = pixelData[i*3 + 0];
            pointer->G = pixelData[i*3 + 1];
            pointer->B = pixelData[i*3 + 2];
            pointer->A = byte.MaxValue;
            pointer++;
        }

        var document = new Document(pixelWidth, pixelHeight);

        document.Layers.Add(layer);

        return document;
    }

    protected override void OnSaveT(Document input, Stream output, PropertyBasedSaveConfigToken token, Surface scratchSurface, ProgressEventHandler progressCallback)
    {
        throw new NotImplementedException();
    }

    public override PropertyCollection OnCreateSavePropertyCollection()
    {
        throw new NotImplementedException();
    }
}

 

Any suggestions are welcome! 😃

Link to comment
Share on other sites

Paint.NET doesn't handle thumbnails for plugins, unfortunately. This would be very complex, for one, but also it's important to note that it would require loading all of the plugins into the process that handles thumbnails. This could cause thumbnails to generate very slowly, and if a plugin contains a bug* it could jeopardize all thumbnail generation. It's also difficult to correctly handle registration of new file types with the shell (Explorer). It's a big Pandora's box of trouble, in other words. Would be nice if it weren't, though.

 

* yes, it happens ... a lot, in fact

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

It depends on the type of shell extension. For extensions that are hosted out-of-process, like thumbnail providers, it should be fine. However, there are still some open questions about how Explorer re-uses the process(es) for extensions. You can only load .NET into a process once, and if Explorer recycles the process then it may not work, particularly if extensions need different versions of .NET. I haven't seen any reports of issues stemming from this, however, so I just have to assume right now that it's safe.

The Paint.NET Blog: https://blog.getpaint.net/

Donations are always appreciated! https://www.getpaint.net/donate.html

forumSig_bmwE60.jpg

Link to comment
Share on other sites

Yes, I've actually coded the plugin and can successfully load any TIM file. However, I'm currently having conceptual issues that, unless I'm mistaken, won't be solvable through the actual PDN interface. This obviously makes sense as PDN is a general image editor and doesn't intend to support a very specific feature for a specific format.

 

Not sure what to do next... I've uploaded my work in case someone has an idea, if that ever makes sense.😁

 

https://forums.getpaint.net/topic/119542-any-possibility-of-load-options-for-a-plugin/?do=findComment&comment=592590

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...