GifPropertyItemInternal.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using HandyControl.Tools.Interop;
  4. namespace HandyControl.Data;
  5. [StructLayout(LayoutKind.Sequential)]
  6. public class GifPropertyItemInternal : IDisposable
  7. {
  8. public int id;
  9. public int len;
  10. public short type;
  11. public IntPtr value = IntPtr.Zero;
  12. internal GifPropertyItemInternal()
  13. {
  14. }
  15. public byte[] Value
  16. {
  17. get
  18. {
  19. if (len == 0)
  20. return null;
  21. var bytes = new byte[len];
  22. Marshal.Copy(value,
  23. bytes,
  24. 0,
  25. len);
  26. return bytes;
  27. }
  28. }
  29. public void Dispose()
  30. {
  31. Dispose(true);
  32. }
  33. ~GifPropertyItemInternal()
  34. {
  35. Dispose(false);
  36. }
  37. private void Dispose(bool disposing)
  38. {
  39. if (value != IntPtr.Zero)
  40. {
  41. Marshal.FreeHGlobal(value);
  42. value = IntPtr.Zero;
  43. }
  44. if (disposing)
  45. GC.SuppressFinalize(this);
  46. }
  47. internal static GifPropertyItemInternal ConvertFromPropertyItem(GifPropertyItem propItem)
  48. {
  49. var propItemInternal = new GifPropertyItemInternal
  50. {
  51. id = propItem.Id,
  52. len = 0,
  53. type = propItem.Type
  54. };
  55. var propItemValue = propItem.Value;
  56. if (propItemValue != null)
  57. {
  58. var length = propItemValue.Length;
  59. propItemInternal.len = length;
  60. propItemInternal.value = Marshal.AllocHGlobal(length);
  61. Marshal.Copy(propItemValue, 0, propItemInternal.value, length);
  62. }
  63. return propItemInternal;
  64. }
  65. internal static GifPropertyItem[] ConvertFromMemory(IntPtr propdata, int count)
  66. {
  67. var props = new GifPropertyItem[count];
  68. for (var i = 0; i < count; i++)
  69. {
  70. GifPropertyItemInternal propcopy = null;
  71. try
  72. {
  73. propcopy = (GifPropertyItemInternal) InteropMethods.PtrToStructure(propdata,
  74. typeof(GifPropertyItemInternal));
  75. props[i] = new GifPropertyItem
  76. {
  77. Id = propcopy.id,
  78. Len = propcopy.len,
  79. Type = propcopy.type,
  80. Value = propcopy.Value
  81. };
  82. // this calls Marshal.Copy and creates a copy of the original memory into a byte array.
  83. propcopy.value = IntPtr.Zero; // we dont actually own this memory so dont free it.
  84. }
  85. finally
  86. {
  87. propcopy?.Dispose();
  88. }
  89. propdata = (IntPtr) ((long) propdata + Marshal.SizeOf(typeof(GifPropertyItemInternal)));
  90. }
  91. return props;
  92. }
  93. }