d2phap/ImageGlass · error · InvalidDataException

IGE: Native codec '{proxy.CodecId}' reported zero frames for

Error message

IGE: Native codec '{proxy.CodecId}' reported zero frames for '{metadata.FilePath}'.

What it means

Thrown by NativePluginAnimator.Create when the plugin returned IGStatus.OK from GetAnimationInfo but the IGAnimationInfo struct is empty: FrameCount <= 0 or the Frames pointer is null. The plugin claimed success but produced no frames, so the host cannot build a frame timing array.

Source

Thrown at source/ImageGlass.Lib/Plugins/NativePluginAnimator.cs:111

                    $"managed exception during GetAnimationInfo: {ex.Message}");
                throw new InvalidDataException(
                    $"IGE: Native codec '{proxy.CodecId}' threw during GetAnimationInfo of '{metadata.FilePath}'.", ex);
            }

            if (status == IGStatus.Canceled)
            {
                token.ThrowIfCancellationRequested();
            }
            if (status != IGStatus.OK)
            {
                throw new InvalidDataException(
                    $"IGE: Native codec '{proxy.CodecId}' returned status {status} for GetAnimationInfo of '{metadata.FilePath}'.");
            }
            infoOwned = true;

            if (info.FrameCount <= 0 || info.Frames == null)
            {
                throw new InvalidDataException(
                    $"IGE: Native codec '{proxy.CodecId}' reported zero frames for '{metadata.FilePath}'.");
            }

            // PHASE 2: copy per-frame timing into the SKCodecFrameInfo[] expected by AnimatorImpl.
            // Only Duration + AlphaType are meaningful here -- the host does not composite.
            var frames = new SKCodecFrameInfo[info.FrameCount];
            for (var i = 0; i < info.FrameCount; i++)
            {
                var f = info.Frames[i];
                frames[i] = new SKCodecFrameInfo
                {
                    Duration = f.DurationMs,
                    AlphaType = f.HasAlpha != 0 ? SKAlphaType.Unpremul : SKAlphaType.Opaque,
                };
            }

            var animator = new NativePluginAnimator(proxy, metadata, frames)
            {

View on GitHub (pinned to 4a3c4fecef)

Solutions

  1. Report to the plugin author: GetAnimationInfo returned OK with FrameCount<=0 or Frames=null, which violates the contract.
  2. Rebuild the plugin and verify its GetAnimationInfo populates IGAnimationInfo.Frames (a caller-allocated array of IGAnimationFrameInfo) and sets FrameCount > 0 on the success path.
  3. Verify the IGAnimationInfo struct field order matches the SDK header in both plugin and host.
  4. Disable the plugin and decode the file with a built-in animator.

Example fix

// before
if (info.FrameCount <= 0 || info.Frames == null)
    throw new InvalidDataException($"IGE: Native codec '{proxy.CodecId}' reported zero frames for '{metadata.FilePath}'.");

// after — name which field was bad so the plugin author can locate it
if (info.FrameCount <= 0 || info.Frames == null)
    throw new InvalidDataException(
        $"IGE: Native codec '{proxy.CodecId}' reported zero frames for '{metadata.FilePath}' " +
        $"(FrameCount={info.FrameCount}, Frames={(info.Frames == null ? "null" : "ok")}).");
Defensive patterns

Strategy: validation

Validate before calling

// After GetAnimationInfo returns OK, sanity-check the populated struct.
if (info.FrameCount <= 0 || info.Frames == null)
    throw new InvalidDataException("Plugin returned OK but no frames");

Type guard

static bool HasFrames(in IGAnimationInfo info) =>
    info.FrameCount > 0 && info.Frames != null;

Try / catch

try { return NativePluginAnimator.Create(proxy, metadata, token); }
catch (InvalidDataException ex) when (ex.Message.Contains("zero frames"))
{ _failureManager.RecordSoftFailure(proxy.Plugin.PluginId, "zero frames on OK"); return null; }

Prevention

When it happens

Trigger: Produced at NativePluginAnimator.cs:111 when info.FrameCount <= 0 || info.Frames == null after a successful GetAnimationInfo. The plugin reported OK but its animation info is structurally empty.

Common situations: Plugin bug: GetAnimationInfo returns OK without populating Frames/FrameCount (e.g. allocates the info struct but does not fill the frame array); ABI mismatch swapping FrameCount with another field so it reads as zero; plugin parsed a file with zero frames but still returned OK instead of InvalidData; plugin's animation-info allocator failed silently.

Related errors


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