I don't think you are going to manage to write a complete solution using just the System.Windows.Imaging.Media namespace as I think you then are completely dependent on the Windows Imaging Codec (WIC) system arbitrating which codec decoder gets used for each image file extension you list that you can support, which would be completely subject to the number of codecs installed for each and the manufacturer supplied ones would likely be given the priority. Accordingly, I think you are going to have to use the wrappers, and just in case you aren't familiar with producing those I included a couple of examples in my last post, but forgot to use the Code markers for proper indentation, etc. As follows:
The ISequentialStream interface wrapper:
using System;
using System.Runtime.InteropServices;
namespace WIC {
[ComImport, Guid("0c733a30-2a1c-11ce-ade5-00aa0044773d"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface ISequentialStream {
[PreserveSig]
int Read(
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv,
[in] uint cb,
[Out] out uint cbRead);
[PreserveSig]
int Write(
[in, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv,
[in] uint cb,
[Out] out uint cbWritten);
}
}
and the IStream interface wrapper, which adds to it:
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace WIC {
[ComImport, Guid("0000000C-0000-0000-C000-000000000046"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IStream : ISequentialStream {
[PreserveSig]
new int Read(
[Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv,
[in] uint cb,
[Out] out uint cbRead);
[PreserveSig]
new int Write(
[in, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pv,
[in] uint cb,
[Out] out uint cbWritten);
[PreserveSig]
int Seek(
[in] long dlibMove,
[in] uint dwOrigin,
[Out] out ulong libNewPosition);
[PreserveSig]
int SetSize(
[in] ulong libNewSize);
[PreserveSig]
int CopyTo(
[in, MarshalAs(UnmanagedType.Interface)] IStream stm,
[in] ulong cb,
[Out] out ulong cbRead,
[Out] out ulong cbWritten);
[PreserveSig]
int Commit(
[in] uint grfCommitFlags);
[PreserveSig]
int Revert();
[PreserveSig]
int LockRegion(
[in] ulong libOffset,
[in] ulong cb,
[in] uint dwLockType);
[PreserveSig]
int UnlockRegion(
[in] ulong libOffset,
[in] ulong cb,
[in] uint dwLockType);
[PreserveSig]
int Stat(
[Out] out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg,
[in] uint grfStatFlag);
[PreserveSig]
int Clone(
[Out, MarshalAs(UnmanagedType.Interface)] out IStream stm);
}
}
In case you've never produced these before, you need to declare the methods in the exact order that they are declared in the C++ header files and an interface that builds on another interface needs to redeclare all the same methods as the previous interface(s) first with the new keyword as IStream above is based on ISequentialStream. The above two interfaces allow you to create a wrapper class for the Stream object that is passed to your OnLoad method for your FileType class so that you can pass the IStream interface pointer as an argument to the decoders and not have to do this by getting a file name. As Rick says, at some point you might be passed a MemoryStream rather than a FileStream and the FileName would not apply.
As to wanting your plugin to work with any installed codec, that is entirely a matter of your program logic as to what you do once you have enumerated all installed codecs: You can put first priority on the FPV ones if they are found and revert to just providing a generic handling and let WIC arbitrate for any others for that file type if they exist and the FPV one does not. Also, I think you should create different FileType classes for each file extension handled and either link them to to the specific FPV codec or to the generic case; in this way you can automatically support all image file classes by getting the file extensions supported from the decoder enumeration, which would avoid requests such as ks8802's for support for the Panasonic '.rw2' file type as below.
I think your method should always work as you seem to use the same method as used by Rick Brewster in his WIC codec support for the HD file format (now WDF or other). I'm sure you must be used to using Reflector to see what others are doing in their code, just as I can see what you are doing with yours?
There are actually even further capabilities you could add, as the FPV decoders support the IWICDevelopRaw interface (or at least some of them do) and allow you to do exposure adjustments to the raw development before it would be passed to Paint.NET. This would require a bit of a user interface form with a histogram, an image preview (preferably with clipping flashies), and EV adjustment slider and value adjustment controls, but would make this more resemble a full raw development plugin for Paint.NET!
Regards, Gordon