2

Windows Imaging Component is used for decoding heif images. However extra apps from the microsoft store (heif image extension, hevc video extensions) are required for a successful decoding of the images.

Without them the WIC api returns blank image. Now I want to be able to programatically determine whether the heif file can be correctly decoded.

I have tried to locate the existence of required decoder type using DXVA Checker which is supposed to be WIC_HEIF_Decoder. But I can't find it registered anywhere.

enter image description here

There is a GUID key however CLSID_WICHeifDecoder documented here which I think can be registered in the system even if the decoder is missing.

Does anyone have any idea how to do this?

mbaros
  • 797
  • 5
  • 23
  • What is "WIC_HEIF_Decoder"? The Microsoft-provided HEIF/HEIC guid is CLSID_WICHeifDecoder. If it's registered then WIC can decode HEIF/HEIC image (but indeed, not all Windows have it installed, and in this case, it won't be registered). What are you trying to do exactly? – Simon Mourier Oct 10 '20 at 16:18
  • This is exactly one of the problems. On a machine CLSID_WICHeifDecoder is defined but the actual implementation is missing – mbaros Oct 10 '20 at 16:39
  • What do you mean by "defined"? – Simon Mourier Oct 10 '20 at 17:02
  • DEFINE_GUID https://docs.microsoft.com/en-us/windows-hardware/drivers/kernel/defining-and-exporting-new-guids – mbaros Oct 10 '20 at 17:32
  • Any guid definition can compile. I means nothing about what's installed on the machine you're running on. The fact that you're compiling doesn't mean it's registered. Just try to decode a .heic file and tells us what error you have and show your code. – Simon Mourier Oct 10 '20 at 18:06
  • 1
    Microsoft introduced a HEIC codec mess with recent Windows 10 update by adding the HEIC GUID without actually installing the h265 image decoder. The HEIC decoder is just about the files structure, but not the actual image decoding. User must pay 1$ to download from Windows Store the actual h265 codec. The easiest solution is to just install the free CopyTrans HEIC WIC decoder https://www.copytrans.net/copytransheic/. On the page it's not clear that is WIC codec, but that's what it is actually. It contains both HEIC file format + h265 decoder. – Niki Feb 01 '21 at 09:27

2 Answers2

3

If you plan to use WIC decoder, you should rather use WIC API to check the availability and not Media Foundation API, even if both decoders are known - at the moment - to be packaged together and belong to the same Windows Store application (extension).

You should be able to use IWICImagingFactory::CreateComponentEnumerator to enumerate decoders and identify if HEIF is among the available ones.

Microsoft HEIF Decoder

  • Class Identifier: CLSID_WICHeifDecoder
  • Signing Status: WICComponentSigned
  • Author: Microsoft
  • Vendor Identifier: {F0E749CA-EDEF-4589-A73A-EE0E626A2A2B}
  • Version: 1.0.0.0
  • Spec Version: 1.0.0.0
  • Friendly Name: Microsoft HEIF Decoder
  • IWICBitmapCodecInfo:
    • Container Format: GUID_ContainerFormatHeif
    • Pixel Formats: GUID_WICPixelFormat32bppBGR
    • Color Management Version: 1.0.0.0
    • MIME Types: image/heic,image/heif,image/avci,image/heic-sequence,image/heif-sequence,image/avcs,image/avif,image/avif-sequence
    • File Extensions: .heic,.heif,.avci,.heics,.heifs,.avcs,.avif,.avifs
    • Patterns: 576

You might prefer to use IWICImagingFactory::CreateDecoder with GUID_ContainerFormatHeif because you should be more interested in ability to decode rather that in specific decoder implementation.

Check for specific CLSID is trivial, using either registry query or direct CoCreateInstance call but it does not make much sense for the specified task.

Roman R.
  • 64,446
  • 5
  • 83
  • 139
  • 2
    Looks like today isn't a good day to write answers. This is only one of several inexplicable down-votes observed today. – IInspectable Oct 10 '20 at 15:46
  • @Roman I did exactly what you said. On a machine that is not able to view/decode heif files I get the decoder listed Author: Microsoft Name: Microsoft HEIF Decoder Extensions: .heic,.heif,.avci,.heics,.heifs,.avcs,.avif,.avifs Version: 1.0.0.0 CLSID: {E9A4A80A-44FE-4DE4-8971-7150B10A5199} – mbaros Oct 10 '20 at 17:47
  • Also FYI one another way to create decoder is to QI `IWICBitmapDecoderInfo` from enumerated `IWICComponentInfo` and do `IWICBitmapDecoderInfo::CreateInstance`. In the case of HEIF decoder there might be (just speculation, I did not check) registration information present without HEIF extension, but even if this is true I would instance creation fail. – Roman R. Oct 10 '20 at 20:22
  • CreateDecoder also returns no errors for that machine – mbaros Oct 12 '20 at 09:17
  • If you can create an instance of the decoder then it's apparently present in the system. It does not look like your check whether decoder/package is installed can answer the question whether certain HEIF images can be decoded. It may be the problem of incompatible or wrong image instead. – Roman R. Oct 12 '20 at 09:30
  • Whatever you are saying makes a big sense, but, apparently, absolutely 0 HEIF images are being decoded without MFVideoFormat_HEVC (hevc video extension) installed – mbaros Oct 12 '20 at 18:13
  • 1
    OK, I got myself updated. HEIF is container format with structure similar to MOV/MP4 ("single frame video"). It can have multiple encodings in it so HEIF WIC codec does not mean you can open HEIC flavor yet so indeed you need to have HEVC decoder as well. So you actually need to have both HEIF and HEVC to open HEIC. Microsoft does not make it obvious how these pieces relate one to another but generally your approach is correct (I think you `MFT_ENUM_FLAG_SYNCMFT` needs to be removed from your code snippet though - GPU backed decoders are asynchronous). – Roman R. Oct 12 '20 at 18:47
1

Since the HEIF decoders are still recognized on Windows that can't decode them this is the best hack imo:

In order to decode HEIF images HEVC video extension should be installed on the machine. So the right check is to see if there is any decoding type matching the HEVC input

MFStartup(MF_VERSION);
IMFActivate** activate {};
unsigned int count {};
// Set the HEVC GUID
MFT_REGISTER_TYPE_INFO input;
input.guidMajorType = MFMediaType_Video;
input.guidSubtype = MFVideoFormat_HEVC;
// Get all available output types for HEVC input
MFTEnumEx(MFT_CATEGORY_VIDEO_DECODER, MFT_ENUM_FLAG_SORTANDFILTER | MFT_ENUM_FLAG_SYNCMFT, &input, nullptr, &activate, &count);
// Release interface pointers
for (size_t i = 0; i < count; i++) {
    activate[i]->Release();
}
CoTaskMemFree(activate);
MFShutdown();
return (count > 0);
mbaros
  • 797
  • 5
  • 23