using System; using System.Runtime.InteropServices; using HandyControl.Tools.Interop; namespace HandyControl.Data; [StructLayout(LayoutKind.Sequential)] public class GifPropertyItemInternal : IDisposable { public int id; public int len; public short type; public IntPtr value = IntPtr.Zero; internal GifPropertyItemInternal() { } public byte[] Value { get { if (len == 0) return null; var bytes = new byte[len]; Marshal.Copy(value, bytes, 0, len); return bytes; } } public void Dispose() { Dispose(true); } ~GifPropertyItemInternal() { Dispose(false); } private void Dispose(bool disposing) { if (value != IntPtr.Zero) { Marshal.FreeHGlobal(value); value = IntPtr.Zero; } if (disposing) GC.SuppressFinalize(this); } internal static GifPropertyItemInternal ConvertFromPropertyItem(GifPropertyItem propItem) { var propItemInternal = new GifPropertyItemInternal { id = propItem.Id, len = 0, type = propItem.Type }; var propItemValue = propItem.Value; if (propItemValue != null) { var length = propItemValue.Length; propItemInternal.len = length; propItemInternal.value = Marshal.AllocHGlobal(length); Marshal.Copy(propItemValue, 0, propItemInternal.value, length); } return propItemInternal; } internal static GifPropertyItem[] ConvertFromMemory(IntPtr propdata, int count) { var props = new GifPropertyItem[count]; for (var i = 0; i < count; i++) { GifPropertyItemInternal propcopy = null; try { propcopy = (GifPropertyItemInternal) InteropMethods.PtrToStructure(propdata, typeof(GifPropertyItemInternal)); props[i] = new GifPropertyItem { Id = propcopy.id, Len = propcopy.len, Type = propcopy.type, Value = propcopy.Value }; // this calls Marshal.Copy and creates a copy of the original memory into a byte array. propcopy.value = IntPtr.Zero; // we dont actually own this memory so dont free it. } finally { propcopy?.Dispose(); } propdata = (IntPtr) ((long) propdata + Marshal.SizeOf(typeof(GifPropertyItemInternal))); } return props; } }