ImageCodecInfo.cs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. using System;
  2. using System.Diagnostics.CodeAnalysis;
  3. using System.Runtime.InteropServices;
  4. using HandyControl.Tools.Interop;
  5. namespace HandyControl.Data;
  6. internal sealed class ImageCodecInfo
  7. {
  8. private string _dllName;
  9. public Guid Clsid { get; set; }
  10. public Guid FormatID { get; set; }
  11. public string CodecName { get; set; }
  12. public string DllName
  13. {
  14. [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity")]
  15. get
  16. {
  17. if (_dllName != null)
  18. {
  19. new System.Security.Permissions.FileIOPermission(System.Security.Permissions.FileIOPermissionAccess.PathDiscovery, _dllName).Demand();
  20. }
  21. return _dllName;
  22. }
  23. [SuppressMessage("Microsoft.Security", "CA2103:ReviewImperativeSecurity")]
  24. set
  25. {
  26. if (value != null)
  27. {
  28. new System.Security.Permissions.FileIOPermission(System.Security.Permissions.FileIOPermissionAccess.PathDiscovery, value).Demand();
  29. }
  30. _dllName = value;
  31. }
  32. }
  33. public string FormatDescription { get; set; }
  34. public string FilenameExtension { get; set; }
  35. public string MimeType { get; set; }
  36. public ImageCodecFlags Flags { get; set; }
  37. public int Version { get; set; }
  38. public byte[][] SignaturePatterns { get; set; }
  39. public byte[][] SignatureMasks { get; set; }
  40. public static ImageCodecInfo[] GetImageDecoders()
  41. {
  42. ImageCodecInfo[] imageCodecs;
  43. var status = InteropMethods.Gdip.GdipGetImageDecodersSize(out var numDecoders, out var size);
  44. if (status != InteropMethods.Gdip.Ok)
  45. {
  46. throw InteropMethods.Gdip.StatusException(status);
  47. }
  48. var memory = Marshal.AllocHGlobal(size);
  49. try
  50. {
  51. status = InteropMethods.Gdip.GdipGetImageDecoders(numDecoders, size, memory);
  52. if (status != InteropMethods.Gdip.Ok)
  53. {
  54. throw InteropMethods.Gdip.StatusException(status);
  55. }
  56. imageCodecs = ConvertFromMemory(memory, numDecoders);
  57. }
  58. finally
  59. {
  60. Marshal.FreeHGlobal(memory);
  61. }
  62. return imageCodecs;
  63. }
  64. public static ImageCodecInfo[] GetImageEncoders()
  65. {
  66. ImageCodecInfo[] imageCodecs;
  67. var status = InteropMethods.Gdip.GdipGetImageEncodersSize(out var numEncoders, out var size);
  68. if (status != InteropMethods.Gdip.Ok)
  69. {
  70. throw InteropMethods.Gdip.StatusException(status);
  71. }
  72. var memory = Marshal.AllocHGlobal(size);
  73. try
  74. {
  75. status = InteropMethods.Gdip.GdipGetImageEncoders(numEncoders, size, memory);
  76. if (status != InteropMethods.Gdip.Ok)
  77. {
  78. throw InteropMethods.Gdip.StatusException(status);
  79. }
  80. imageCodecs = ConvertFromMemory(memory, numEncoders);
  81. }
  82. finally
  83. {
  84. Marshal.FreeHGlobal(memory);
  85. }
  86. return imageCodecs;
  87. }
  88. public static ImageCodecInfo[] ConvertFromMemory(IntPtr memoryStart, int numCodecs)
  89. {
  90. var codecs = new ImageCodecInfo[numCodecs];
  91. int index;
  92. for (index = 0; index < numCodecs; index++)
  93. {
  94. var curcodec = (IntPtr) ((long) memoryStart + Marshal.SizeOf(typeof(InteropValues.ImageCodecInfoPrivate)) * index);
  95. var codecp = new InteropValues.ImageCodecInfoPrivate();
  96. InteropMethods.PtrToStructure(curcodec, codecp);
  97. codecs[index] = new ImageCodecInfo
  98. {
  99. Clsid = codecp.Clsid,
  100. FormatID = codecp.FormatID,
  101. CodecName = Marshal.PtrToStringUni(codecp.CodecName),
  102. DllName = Marshal.PtrToStringUni(codecp.DllName),
  103. FormatDescription = Marshal.PtrToStringUni(codecp.FormatDescription),
  104. FilenameExtension = Marshal.PtrToStringUni(codecp.FilenameExtension),
  105. MimeType = Marshal.PtrToStringUni(codecp.MimeType),
  106. Flags = (ImageCodecFlags) codecp.Flags,
  107. Version = codecp.Version,
  108. SignaturePatterns = new byte[codecp.SigCount][],
  109. SignatureMasks = new byte[codecp.SigCount][]
  110. };
  111. for (var j = 0; j < codecp.SigCount; j++)
  112. {
  113. codecs[index].SignaturePatterns[j] = new byte[codecp.SigSize];
  114. codecs[index].SignatureMasks[j] = new byte[codecp.SigSize];
  115. Marshal.Copy((IntPtr) ((long) codecp.SigMask + j * codecp.SigSize), codecs[index].SignatureMasks[j], 0, codecp.SigSize);
  116. Marshal.Copy((IntPtr) ((long) codecp.SigPattern + j * codecp.SigSize), codecs[index].SignaturePatterns[j], 0, codecp.SigSize);
  117. }
  118. }
  119. return codecs;
  120. }
  121. }