d2phap/ImageGlass · error · InvalidDataException

IGE: Native codec '{CodecId}' returned an unsupported pixel

Error message

IGE: Native codec '{CodecId}' returned an unsupported pixel format ({buffer.PixelFormat}).

What it means

Thrown by NativeCodecProxy.WrapPluginBufferAsImage when MapPixelFormat returns SKColorType.Unknown for the buffer's declared IGPixelFormat. The host supports a fixed set of pixel formats (Bgra8Unorm and a few others); the plugin picked a format outside that set, so Skia cannot interpret the bytes.

Source

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

    /// <summary>
    /// Wraps a plugin-owned <see cref="IGPixelBuffer"/> in an <see cref="SKImage"/>
    /// without copying the pixels. The returned image owns the plugin buffer:
    /// disposing the image calls back into the plugin's <c>FreePixelBuffer</c>
    /// via the release delegate (which the SDK contract requires to be thread-safe).
    /// </summary>
    internal SKImage WrapPluginBufferAsImage(in IGPixelBuffer buffer, SKColorSpace? srcColorSpace)
    {
        // Validate the buffer before we hand it to Skia.
        if (buffer.Data == null || buffer.Width <= 0 || buffer.Height <= 0)
        {
            throw new InvalidDataException(
                $"IGE: Native codec '{CodecId}' returned an invalid pixel buffer.");
        }

        var (colorType, alphaType) = MapPixelFormat((IGPixelFormat)buffer.PixelFormat);
        if (colorType == SKColorType.Unknown)
        {
            throw new InvalidDataException(
                $"IGE: Native codec '{CodecId}' returned an unsupported pixel format ({buffer.PixelFormat}).");
        }

        var info = new SKImageInfo(buffer.Width, buffer.Height, colorType, alphaType);
        if (srcColorSpace is not null)
        {
            info = info.WithColorSpace(srcColorSpace);
        }

        // Carrier holds the plugin codec API + a copy of the buffer descriptor so
        // SkiaSharp can hand the pointer back to the plugin on dispose.
        var carrier = new PluginPixelBufferRelease
        {
            CodecApiPtr = (nint)_codecApi,
            Buffer = buffer,
            PluginId = _plugin.PluginId,
            LiveToken = _plugin.LiveToken,
        };

View on GitHub (pinned to 4a3c4fecef)

Solutions

  1. Have the plugin output one of the host-supported formats — Bgra8Unorm is the canonical one (see ReadPixelsInto comment about why BGRA Unpremul is mandatory).
  2. Update MapPixelFormat in NativeCodecProxy if a new legitimate format was added to the SDK and the host should accept it.
  3. Verify the plugin is built against the same IGPixelFormat enum values as the host (no enum drift).
  4. Disable the plugin and let a built-in codec decode the file in a host-native format.

Example fix

// before
var (colorType, alphaType) = MapPixelFormat((IGPixelFormat)buffer.PixelFormat);
if (colorType == SKColorType.Unknown)
    throw new InvalidDataException($"IGE: Native codec '{CodecId}' returned an unsupported pixel format ({buffer.PixelFormat}).");

// after — name the enum value so the plugin author knows which format was rejected
var (colorType, alphaType) = MapPixelFormat((IGPixelFormat)buffer.PixelFormat);
if (colorType == SKColorType.Unknown)
    throw new InvalidDataException(
        $"IGE: Native codec '{CodecId}' returned an unsupported pixel format " +
        $"({(IGPixelFormat)buffer.PixelFormat} = {buffer.PixelFormat}). Supported: Bgra8Unorm.");
Defensive patterns

Strategy: validation

Validate before calling

// Before WrapPluginBufferAsImage, check the format maps to a known Skia color type.
var (ct, _) = MapPixelFormat((IGPixelFormat)buffer.PixelFormat);
if (ct == SKColorType.Unknown)
    throw new InvalidDataException($"Plugin returned unsupported format {(IGPixelFormat)buffer.PixelFormat}");

Type guard

static bool IsSupportedFormat(IGPixelFormat f) =>
    MapPixelFormat(f).colorType != SKColorType.Unknown;

Try / catch

try { image = proxy.WrapPluginBufferAsImage(in buffer, colorSpace); }
catch (InvalidDataException ex) when (ex.Message.Contains("unsupported pixel format"))
{ _log.Warn($"Plugin {proxy.CodecId} emitted {buffer.PixelFormat}; requesting Bgra8Unorm."); return BuiltInFallback(metadata); }

Prevention

When it happens

Trigger: Produced at NativeCodecProxy.cs:807 when the IGPixelFormat in IGPixelBuffer.PixelFormat does not map to any known SKColorType. The plugin successfully produced pixels but in a layout the host cannot consume.

Common situations: Plugin author chose a format not in the host's MapPixelFormat table (e.g. a Planar YUV, a 16-bit planar HDR, or a vendor-specific format); ABI drift where PixelFormat lands at the wrong offset and reads as a garbage int; plugin built against an older SDK that used different IGPixelFormat enum values.

Related errors


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