d2phap/ImageGlass · error · NotSupportedException

Native codec '{CodecId}' does not support static-raster deco

Error message

Native codec '{CodecId}' does not support static-raster decode.

What it means

Thrown by NativeCodecProxy.DecodeCore when the loaded native codec's ABI table is missing the DecodeStaticRaster or FreePixelBuffer function pointers. The plugin DLL loaded and exposed its codec API, but it does not implement the static (single-frame) raster decode contract — it is either an animation-only codec, an encoder-only plugin, or an older SDK build that predates the decode entry points.

Source

Thrown at source/ImageGlass.Lib/Plugins/NativeCodecProxy.cs:374

            }
        }
        finally
        {
            PluginHostApiTable.ReleaseCancellation(cancelHandle);
            _plugin.LiveToken.Exit();
        }
        return meta;
    }


    /// <summary>
    /// Invokes the plugin decode entry point and wraps the returned pixel buffer in a codec result.
    /// </summary>
    private CodecDecodeResult DecodeCore(PhotoMetadata metadata, int frameIndex, CancellationToken token)
    {
        if (_codecApi->DecodeStaticRaster == null || _codecApi->FreePixelBuffer == null)
        {
            throw new NotSupportedException($"Native codec '{CodecId}' does not support static-raster decode.");
        }

        // hold the plugin alive (see LoadMetadataCore)
        if (!_plugin.LiveToken.TryEnter())
        {
            throw new InvalidDataException($"IGE: Native codec '{CodecId}' was unloaded.");
        }

        // Register cancellation before entering native code and keep track of buffer ownership.
        var cancelHandle = PluginHostApiTable.RegisterCancellation(token);
        var filePath = metadata.FilePath;
        IGPixelBuffer buffer = default;
        var bufferOwned = false;
        var ownershipTransferred = false;

        try
        {
            IGStatus status;

View on GitHub (pinned to 4a3c4fecef)

Solutions

  1. Confirm with the plugin author that the plugin supports static-raster decode for the target format; if it is animation-only, register it only for animated containers.
  2. Rebuild the plugin against the current ImageGlass plugin SDK so its codec API exports DecodeStaticRaster and FreePixelBuffer.
  3. Check the plugin manifest's declared capabilities and make sure the codec is not registered for an extension it cannot statically decode.
  4. Fall back to a different codec for that extension (remove or disable the plugin from _plugins and let CodecRegistry pick a built-in decoder).

Example fix

// before
if (_codecApi->DecodeStaticRaster == null || _codecApi->FreePixelBuffer == null)
    throw new NotSupportedException($"Native codec '{CodecId}' does not support static-raster decode.");

// after — surface capability from the registry so callers can avoid the codec for static decode
if (_codecApi->DecodeStaticRaster == null || _codecApi->FreePixelBuffer == null)
    throw new NotSupportedException($"Native codec '{CodecId}' does not support static-raster decode. " +
        $"Check that the plugin manifest declares static-decode capability for this extension.");
Defensive patterns

Strategy: validation

Validate before calling

// Before asking a native codec to decode, check the capability it advertises.
if (!proxy.SupportsStaticRasterDecode)
    throw new NotSupportedException($"Codec {proxy.CodecId} cannot statically decode {metadata.FilePath}; pick another codec.");
var result = proxy.DecodeStatic(metadata, frame, token);

Type guard

static bool CanStaticDecode(NativeCodecProxy proxy) =>
    proxy.CodecApi->DecodeStaticRaster != null && proxy.CodecApi->FreePixelBuffer != null;

Try / catch

try { return proxy.DecodeStatic(metadata, frame, token); }
catch (NotSupportedException ex) when (ex.Message.Contains("does not support static-raster decode"))
{ _log.Warn($"Codec {proxy.CodecId} has no static decode; falling back to built-in."); return BuiltInFallback(metadata); }

Prevention

When it happens

Trigger: Produced on the first single-frame decode attempt (codec.DecodeAsync → DecodeCore) when _codecApi->DecodeStaticRaster == null || _codecApi->FreePixelBuffer == null. The codec was registered and selected for a file extension, but its native vtable lacks those slots.

Common situations: A plugin built against an older ImageGlass plugin SDK that did not require DecodeStaticRaster; an encoder plugin mistakenly registered as a decoder; a partial plugin where the author implemented animation decode but not static decode; an extension registered to the wrong codec DLL.

Related errors


AI-assisted analysis of d2phap/ImageGlass@4a3c4fecef (2026-08-13). Data as JSON: /api/errors/385ab33c41c730fb. Report an issue: GitHub.