HandyOrg/HandyControl · error

StatusException(status)

Error message

StatusException(status)

What it means

GDI+ returned a non-Ok status from GdipImageGetFrameDimensionsList while enumerating the frame dimensions of the GIF. The library frees the unmanaged buffer and converts the native status code into a StatusException. It indicates the underlying native image handle rejected the frame-dimension query (corrupt image, wrong format, or disposed handle).

Solutions

  1. Verify the file is a genuine, complete GIF (check magic bytes 'GIF8') before loading
  2. Keep the source stream open and unmodified for the lifetime of the GifImage
  3. Do not access frame data after calling Dispose on the GifImage
  4. Catch the StatusException and fall back to rendering the first frame

Example fix

// before
var dims = gif.FrameDimensionsList;
// after
try { var dims = gif.FrameDimensionsList; }
catch (Exception ex) when (IsGdiPlusStatusError(ex)) { /* fallback: render frame 0 */ }
Defensive patterns

Strategy: try-catch

Validate before calling

static bool LooksLikeGif(byte[] header) => header.Length >= 6 && header[0]=='G' && header[1]=='I' && header[2]=='F';

Type guard

static bool IsAlive(GifImage g) => g != null && !g.IsDisposed;

Try / catch

try { var dims = gif.FrameDimensionsList; }
catch (Exception ex) when (ex is ExternalException || ex.Message.Contains("StatusException")) { /* single-frame fallback */ }

Prevention

When it happens

Trigger: Reading FrameDimensionsList on a GifImage whose native image is corrupt/truncated, or whose handle was disposed, so GdipImageGetFrameDimensionsList returns an error status like Win32Error or InvalidParameter.

Common situations: Loading a file renamed to .gif that is not actually a valid GIF; stream closed or modified while GifImage still uses it; accessing frames after Dispose.

Related errors


AI-assisted analysis of HandyOrg/HandyControl@2c0875ebd6 (2026-09-14). Data as JSON: /api/errors/7b1e016faa8b4bd6. Report an issue: GitHub.

Appendix: source

Thrown at src/Shared/HandyControl_Shared/Controls/Image/GifImage.cs:374

            if (count <= 0)
            {
                return new Guid[0];
            }

            var size = Marshal.SizeOf(typeof(Guid));

            var buffer = Marshal.AllocHGlobal(checked(size * count));
            if (buffer == IntPtr.Zero)
            {
                throw InteropMethods.Gdip.StatusException(InteropMethods.Gdip.OutOfMemory);
            }

            status = InteropMethods.Gdip.GdipImageGetFrameDimensionsList(new HandleRef(this, NativeImage), buffer, count);

            if (status != InteropMethods.Gdip.Ok)
            {
                Marshal.FreeHGlobal(buffer);
                throw InteropMethods.Gdip.StatusException(status);
            }

            var guids = new Guid[count];

            try
            {
                for (var i = 0; i < count; i++)
                {
                    guids[i] = (Guid) InteropMethods.PtrToStructure((IntPtr) ((long) buffer + size * i), typeof(Guid));
                }
            }
            finally
            {
                Marshal.FreeHGlobal(buffer);
            }

            return guids;
        }

View on GitHub (pinned to 2c0875ebd6)