HandyOrg/HandyControl · error
StatusException(InteropMethods.Gdip.OutOfMemory)
Error message
StatusException(InteropMethods.Gdip.OutOfMemory)
What it means
This is a GDI+ StatusException wrapping the OutOfMemory status code, thrown when Marshal.AllocHGlobal fails to allocate unmanaged memory for the frame-dimension GUID buffer. The library throws it because the native allocation returned IntPtr.Zero and proceeding would corrupt the native call. Note: GDI+'s OutOfMemory status often means a generic internal failure, not literally insufficient RAM.
Solutions
- Validate the GIF file loads correctly (e.g. open it with a known-good decoder) before feeding it to GifImage
- Catch OutOfMemoryException/StatusException around GifImage construction and fall back to a static frame
- Run the process as 64-bit or reduce concurrent image allocations to relieve address-space pressure
- Dispose GifImage promptly (it holds a native handle) to avoid leaked unmanaged memory
Example fix
// before
var gif = new GifImage(stream);
// after
GifImage gif = null;
try { gif = new GifImage(stream); }
catch (Exception ex) when (ex is OutOfMemoryException || ex.Source != null && ex.Message.Contains("OutOfMemory"))
{ /* fall back to static rendering */ } Defensive patterns
Strategy: try-catch
Validate before calling
if (buffer == IntPtr.Zero || count <= 0) { /* skip native call, use fallback */ } Type guard
static bool IsUsableGifStream(Stream s) => s != null && s.CanRead && s.Length > 6;
Try / catch
try { var gif = new GifImage(stream); }
catch (OutOfMemoryException) { /* static fallback frame */ } Prevention
- Validate GIF magic bytes before loading
- Dispose GifImage deterministically to free native memory
- Prefer 64-bit processes when handling many images
When it happens
Trigger: Calling into GifImage frame-dimension enumeration (e.g. during initialization or EnsureSave/CanAnimate paths) when AllocHGlobal(checked(size*count)) cannot secure the requested unmanaged block — typically a huge or corrupt frame-dimension count read from a malformed GIF.
Common situations: Corrupt or truncated GIF files that report an absurd frame dimension count; memory pressure in the process (32-bit address space exhaustion); running after the native GDI+ handle has gone bad.
Related errors
- StatusException(status)
- GdiplusInvalidSize
- InteropMethods.Gdip.StatusException(status)
- StatusException(status)
- stream null
AI-assisted analysis of HandyOrg/HandyControl@2c0875ebd6 (2026-09-14).
Data as JSON: /api/errors/f44eb3da50af1b2e.
Report an issue: GitHub.
Appendix: source
Thrown at src/Shared/HandyControl_Shared/Controls/Image/GifImage.cs:366
{
var status = InteropMethods.Gdip.GdipImageGetFrameDimensionsCount(new HandleRef(this, NativeImage), out var count);
if (status != InteropMethods.Gdip.Ok)
{
throw InteropMethods.Gdip.StatusException(status);
}
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));
}View on GitHub (pinned to 2c0875ebd6)