Initial workable WIC support and correct out parameters in other contexts.

This commit is contained in:
Amer Koleci
2022-09-16 12:04:06 +02:00
parent 3f9da136a9
commit 1942a804f8
7 changed files with 858 additions and 792 deletions

View File

@@ -1,6 +1,7 @@
// Copyright © Amer Koleci and Contributors. // Copyright © Amer Koleci and Contributors.
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
using System.ComponentModel.DataAnnotations;
using System.Globalization; using System.Globalization;
using System.Text; using System.Text;
using Newtonsoft.Json; using Newtonsoft.Json;
@@ -61,8 +62,8 @@ public static class Program
{ "Foundation.CHAR", "byte" }, { "Foundation.CHAR", "byte" },
{ "Foundation.LUID", "Luid" }, { "Foundation.LUID", "Luid" },
{ "Foundation.LARGE_INTEGER", "LargeInterger" }, { "Foundation.LARGE_INTEGER", "LargeInteger" },
{ "Foundation.ULARGE_INTEGER", "ULargeInterger" }, { "Foundation.ULARGE_INTEGER", "ULargeInteger" },
{ "System.Com.IUnknown", "IUnknown" }, { "System.Com.IUnknown", "IUnknown" },
{ "System.Com.ISequentialStream", "Com.ISequentialStream" }, { "System.Com.ISequentialStream", "Com.ISequentialStream" },
@@ -92,6 +93,8 @@ public static class Program
{ "Graphics.Direct2D.Common.D2D_VECTOR_4F", "Vector4" }, { "Graphics.Direct2D.Common.D2D_VECTOR_4F", "Vector4" },
{ "Graphics.Direct2D.Common.D2D_SIZE_F", "System.Drawing.SizeF" }, { "Graphics.Direct2D.Common.D2D_SIZE_F", "System.Drawing.SizeF" },
{ "Graphics.Imaging.WICRect", "System.Drawing.Rectangle" },
// TODO: Understand those -> // TODO: Understand those ->
{ "Foundation.RECT", "RawRect" }, { "Foundation.RECT", "RawRect" },
{ "Foundation.RECTL", "RawRect" }, { "Foundation.RECTL", "RawRect" },
@@ -691,6 +694,21 @@ public static class Program
{ "WICColorContextType", "WICColorContext" }, { "WICColorContextType", "WICColorContext" },
{ "WICBitmapCreateCacheOption", "WICBitmap" }, { "WICBitmapCreateCacheOption", "WICBitmap" },
{ "WICDecodeOptions", "WICDecodeMetadata" }, { "WICDecodeOptions", "WICDecodeMetadata" },
{ "WICBitmapEncoderCacheOption", "WICBitmapEncoder" },
{ "WICComponentType", "WIC" },
{ "WICComponentEnumerateOptions", "WICComponentEnumerate" },
{ "WICBitmapInterpolationMode", "WICBitmapInterpolation" },
{ "WICBitmapPaletteType", "WICBitmapPaletteType" },
{ "WICBitmapDitherType", "WICBitmapDitherType" },
{ "WICBitmapAlphaChannelOption", "WICBitmap" },
{ "WICBitmapTransformOptions", "WICBitmapTransform" },
{ "WICBitmapLockFlags", "WICBitmapLock" },
{ "WICBitmapDecoderCapabilities", "WICBitmapDecoderCapability" },
{ "WICProgressOperation", "WICProgressOperation" },
{ "WICProgressNotification", "WICProgressNotification" },
{ "WICComponentSigning", "WICComponent" },
{ "WICPixelFormatNumericRepresentation", "WICPixelFormatNumericRepresentation" },
{ "WICPlanarOptions", "WICPlanarOptions" },
}; };
private static readonly Dictionary<string, string> s_knownEnumValueNames = new() private static readonly Dictionary<string, string> s_knownEnumValueNames = new()
@@ -834,6 +852,7 @@ public static class Program
// WIC // WIC
{ "IWICImagingFactory::CreateDecoderFromFilename::dwDesiredAccess", "NativeFileAccess" }, { "IWICImagingFactory::CreateDecoderFromFilename::dwDesiredAccess", "NativeFileAccess" },
{ "IWICBitmap::Lock::flags", "WICBitmapLockFlags" },
}; };
private static readonly HashSet<string> s_visitedEnums = new(); private static readonly HashSet<string> s_visitedEnums = new();
@@ -1288,6 +1307,7 @@ public static class Program
{ {
string csTypeName; string csTypeName;
string enumPrefix = string.Empty; string enumPrefix = string.Empty;
bool skipPrettify = false;
if (enumType.Name.StartsWith("WIC")) if (enumType.Name.StartsWith("WIC"))
{ {
@@ -1296,6 +1316,7 @@ public static class Program
if (s_knownTypesPrefixes.TryGetValue(enumType.Name, out string? knowPrefix)) if (s_knownTypesPrefixes.TryGetValue(enumType.Name, out string? knowPrefix))
{ {
enumPrefix = knowPrefix!; enumPrefix = knowPrefix!;
skipPrettify = true;
} }
} }
else else
@@ -1351,7 +1372,7 @@ public static class Program
using (writer.PushBlock($"public enum {csTypeName} : {baseTypeName}")) using (writer.PushBlock($"public enum {csTypeName} : {baseTypeName}"))
{ {
if (isFlags && if (isFlags &&
!enumType.Values.Any(item => GetEnumItemName(enumType, item, enumPrefix) == "None")) !enumType.Values.Any(item => GetEnumItemName(enumType, item, enumPrefix, skipPrettify) == "None"))
{ {
writer.WriteLine("None = 0,"); writer.WriteLine("None = 0,");
} }
@@ -1382,7 +1403,7 @@ public static class Program
continue; continue;
} }
string enumValueName = GetEnumItemName(enumType, enumItem, enumPrefix); string enumValueName = GetEnumItemName(enumType, enumItem, enumPrefix, skipPrettify);
if (!autoGenerated) if (!autoGenerated)
{ {
@@ -1406,14 +1427,14 @@ public static class Program
writer.WriteLine(); writer.WriteLine();
} }
private static string GetEnumItemName(ApiType enumType, ApiEnumValue enumItem, string enumPrefix) private static string GetEnumItemName(ApiType enumType, ApiEnumValue enumItem, string enumPrefix, bool skipPrettify)
{ {
if (string.IsNullOrEmpty(enumPrefix)) if (string.IsNullOrEmpty(enumPrefix))
{ {
return enumItem.Name; return enumItem.Name;
} }
string enumValueName = GetPrettyFieldName(enumItem.Name, enumPrefix); string enumValueName = GetPrettyFieldName(enumItem.Name, enumPrefix, skipPrettify);
// D3D11 has some enum name "issues" // D3D11 has some enum name "issues"
// D3D11_FILL_MODE -> D3D11_FILL_* // D3D11_FILL_MODE -> D3D11_FILL_*
@@ -1421,7 +1442,7 @@ public static class Program
{ {
string[] parts = enumType.Name.Split(new[] { '_' }, StringSplitOptions.RemoveEmptyEntries); string[] parts = enumType.Name.Split(new[] { '_' }, StringSplitOptions.RemoveEmptyEntries);
enumPrefix = string.Join("_", parts.Take(parts.Length - 1)); enumPrefix = string.Join("_", parts.Take(parts.Length - 1));
enumValueName = GetPrettyFieldName(enumItem.Name, enumPrefix); enumValueName = GetPrettyFieldName(enumItem.Name, enumPrefix, skipPrettify);
} }
// D3D12 FLAGS/FLAG // D3D12 FLAGS/FLAG
@@ -1429,7 +1450,7 @@ public static class Program
if (enumValueName.StartsWith("D3D12_") && enumType.Name.EndsWith("FLAGS")) if (enumValueName.StartsWith("D3D12_") && enumType.Name.EndsWith("FLAGS"))
{ {
enumPrefix = enumType.Name.Substring(0, enumType.Name.Length - 1); enumPrefix = enumType.Name.Substring(0, enumType.Name.Length - 1);
enumValueName = GetPrettyFieldName(enumItem.Name, enumPrefix); enumValueName = GetPrettyFieldName(enumItem.Name, enumPrefix, skipPrettify);
} }
return enumValueName; return enumValueName;
@@ -1446,7 +1467,8 @@ public static class Program
} }
else else
{ {
if (structType.Name.StartsWith("Dxc")) if (structType.Name.StartsWith("Dxc") ||
structType.Name.StartsWith("WIC"))
{ {
csTypeName = structType.Name; csTypeName = structType.Name;
} }
@@ -1490,7 +1512,7 @@ public static class Program
} }
else else
{ {
fieldValueName = GetPrettyFieldName(field.Name, structPrefix); fieldValueName = GetPrettyFieldName(field.Name, structPrefix, false);
} }
if (structType.Name == "D3D11_OMAC") if (structType.Name == "D3D11_OMAC")
@@ -1615,7 +1637,7 @@ public static class Program
string fieldTypeName = GetTypeName(field.Type); string fieldTypeName = GetTypeName(field.Type);
fieldTypeName = NormalizeTypeName(writer.Api, fieldTypeName); fieldTypeName = NormalizeTypeName(writer.Api, fieldTypeName);
string fieldName = GetPrettyFieldName(field.Name, structPrefix); string fieldName = GetPrettyFieldName(field.Name, structPrefix, false);
writer.WriteLine("[UnscopedRef]"); writer.WriteLine("[UnscopedRef]");
if (fieldTypeName == "Array") if (fieldTypeName == "Array")
@@ -1796,7 +1818,7 @@ public static class Program
string parameterType = string.Empty; string parameterType = string.Empty;
if (method.Name == "GetFrame" && parameter.Name == "ppIBitmapFrame") if (method.Name == "CreateSurface" && parameter.Name == "ppSurface")
{ {
} }
@@ -1845,11 +1867,25 @@ public static class Program
parameterType += "*"; parameterType += "*";
} }
} }
else if (parameter.Attrs.Any(item => item is string str && str == "RetVal")) else if (parameterType.EndsWith("**") == false &&
parameter.Attrs.Any(item => item is string str && (str == "RetVal" || str == "Out")))
{ {
if (!IsPrimitive(parameter.Type)) if (parameter.Type.Child.Kind != "ApiRef")
{ {
parameterType += "*"; if (!IsPrimitive(parameter.Type))
{
parameterType += "*";
}
}
else
{
string apiName = GetApiName(parameter.Type.Child);
string fullTypeName = $"{apiName}.{parameter.Type.Child.Name}";
if (!IsPrimitive(parameter.Type) && !IsStruct(fullTypeName) && !IsEnum(fullTypeName))
{
parameterType += "*";
}
} }
} }
@@ -2050,7 +2086,7 @@ public static class Program
return prettyName; return prettyName;
} }
private static string GetPrettyFieldName(string value, string enumPrefix) private static string GetPrettyFieldName(string value, string enumPrefix, bool skipPrettify)
{ {
if (s_knownEnumValueNames.TryGetValue(value, out string? knownName)) if (s_knownEnumValueNames.TryGetValue(value, out string? knownName))
{ {
@@ -2100,7 +2136,7 @@ public static class Program
continue; continue;
} }
if (s_preserveCaps.Contains(part)) if (s_preserveCaps.Contains(part) || skipPrettify)
{ {
sb.Append(part); sb.Append(part);
} }
@@ -2370,13 +2406,24 @@ public static class Program
case "uint": case "uint":
case "short": case "short":
case "ushort": case "ushort":
case "Bool32": case "long":
case "ulong":
case "float":
case "double":
return true; return true;
case "nint": case "nint":
case "nuint": case "nuint":
case "IntPtr": case "IntPtr":
case "UIntPtr": case "UIntPtr":
case "Guid":
return true;
case "Bool32":
case "LargeInteger":
case "ULargeInteger":
case "Luid":
case "HResult":
return true; return true;
} }

View File

@@ -2145,9 +2145,9 @@ public unsafe partial struct IDxcContainerBuilder
/// <include file='../Direct3D.xml' path='doc/member[@name="IDxcContainerBuilder::SerializeContainer"]/*' /> /// <include file='../Direct3D.xml' path='doc/member[@name="IDxcContainerBuilder::SerializeContainer"]/*' />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
[VtblIndex(6)] [VtblIndex(6)]
public HResult SerializeContainer(IDxcOperationResult* ppResult) public HResult SerializeContainer(IDxcOperationResult** ppResult)
{ {
return ((delegate* unmanaged[Stdcall]<IDxcContainerBuilder*, IDxcOperationResult*, int>)(lpVtbl[6]))((IDxcContainerBuilder*)Unsafe.AsPointer(ref this), ppResult); return ((delegate* unmanaged[Stdcall]<IDxcContainerBuilder*, IDxcOperationResult**, int>)(lpVtbl[6]))((IDxcContainerBuilder*)Unsafe.AsPointer(ref this), ppResult);
} }
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
// Copyright © Amer Koleci and Contributors.
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
using System.Drawing;
namespace Win32.Graphics.Imaging;
/// <summary>
/// A <see langword="class"/> with extensions for the <see cref="IWICBitmapSource"/> type.
/// </summary>
public static unsafe class IWICBitmapSourceExtensions
{
public static HResult CopyPixels<T>(this ref IWICBitmapSource source, int stride, ReadOnlySpan<T> data)
where T : unmanaged
{
fixed (T* dataPtr = data)
{
return source.CopyPixels(null, (uint)stride, (uint)(data.Length * sizeof(T)), (byte*)dataPtr);
}
}
public static HResult CopyPixels<T>(this ref IWICBitmapSource source, Rectangle rect, int stride, ReadOnlySpan<T> data)
where T : unmanaged
{
fixed (T* dataPtr = data)
{
return source.CopyPixels(&rect, (uint)stride, (uint)(data.Length * sizeof(T)), (byte*)dataPtr);
}
}
}

View File

@@ -3,7 +3,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>netstandard2.0;net6.0;</TargetFrameworks> <TargetFrameworks>netstandard2.0;net6.0;</TargetFrameworks>
<Description>Windows API low level bindings.</Description> <Description>Windows API low level bindings.</Description>
<VersionPrefix>1.3.0</VersionPrefix> <VersionPrefix>1.4.0</VersionPrefix>
<VersionSuffix Condition="'$(VersionSuffix)' == ''"></VersionSuffix> <VersionSuffix Condition="'$(VersionSuffix)' == ''"></VersionSuffix>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup> </PropertyGroup>

View File

@@ -1,23 +1,21 @@
// Copyright © Amer Koleci and Contributors. // Copyright © Amer Koleci and Contributors.
// Licensed under the MIT License (MIT). See LICENSE in the repository root for more information. // Licensed under the MIT License (MIT). See LICENSE in the repository root for more information.
using System.Numerics;
using Win32; using Win32;
using Win32.Graphics.Direct3D; using Win32.Graphics.Direct3D;
using Win32.Graphics.Direct3D.Dxc;
using Win32.Graphics.Direct3D11; using Win32.Graphics.Direct3D11;
using Win32.Graphics.Dxgi; using Win32.Graphics.Dxgi;
using Win32.Graphics.Dxgi.Common;
using Win32.Graphics.Imaging;
using static Win32.Apis; using static Win32.Apis;
using static Win32.Graphics.Direct3D.Dxc.Apis;
using static Win32.Graphics.Direct3D11.Apis; using static Win32.Graphics.Direct3D11.Apis;
using static Win32.Graphics.Dxgi.Apis; using static Win32.Graphics.Dxgi.Apis;
using MessageId = Win32.Graphics.Direct3D11.MessageId;
using InfoQueueFilter = Win32.Graphics.Direct3D11.InfoQueueFilter;
using Win32.Graphics.Dxgi.Common;
using System.Numerics;
using Win32.Graphics.Direct3D.Dxc;
using static Win32.Graphics.Direct3D.Dxc.Apis;
using System.Runtime.CompilerServices;
using System.Security.Claims;
using Win32.Graphics.Imaging;
using static Win32.Graphics.Imaging.Apis; using static Win32.Graphics.Imaging.Apis;
using InfoQueueFilter = Win32.Graphics.Direct3D11.InfoQueueFilter;
using MessageId = Win32.Graphics.Direct3D11.MessageId;
namespace ClearScreen; namespace ClearScreen;
@@ -64,6 +62,14 @@ public static unsafe class Program
// Get the first frame of the loaded image (if more are present, they will be ignored) // Get the first frame of the loaded image (if more are present, they will be ignored)
decoder.Get()->GetFrame(0, wicBitmapFrameDecode.GetAddressOf()).ThrowIfFailed(); decoder.Get()->GetFrame(0, wicBitmapFrameDecode.GetAddressOf()).ThrowIfFailed();
uint width;
uint height;
Guid pixelFormat;
wicBitmapFrameDecode.Get()->GetSize(&width, &height).ThrowIfFailed();
wicBitmapFrameDecode.Get()->GetPixelFormat(&pixelFormat).ThrowIfFailed();
//wicBitmapFrameDecode.Get()->CopyPixels(rowPitch, pixels);
} }
public static void Main() public static void Main()