hacks: add NetVips hacks to minimize string allocation
This commit is contained in:
parent
3307c56221
commit
7c637eec3e
2 changed files with 72 additions and 0 deletions
38
src/Oh.My.Stitcher/NetVips/GObjectHacks.cs
Normal file
38
src/Oh.My.Stitcher/NetVips/GObjectHacks.cs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using NetVips.Internal;
|
||||
using GObjectManaged = NetVips.GObject;
|
||||
|
||||
namespace Oh.My.Stitcher.NetVips;
|
||||
|
||||
|
||||
internal static unsafe class GObjectHacks
|
||||
{
|
||||
internal static void SetProperty(GObjectManaged gObject, string name, ReadOnlySpan<byte> value)
|
||||
{
|
||||
var gvStruct = new GValue.Struct();
|
||||
|
||||
try
|
||||
{
|
||||
GValue.Init(ref gvStruct, 16 << 2);
|
||||
fixed( byte* pValue = value )
|
||||
{
|
||||
GValueHacks.SetString(ref gvStruct, pValue);
|
||||
}
|
||||
|
||||
GObject.SetProperty(gObject, name, in gvStruct);
|
||||
}
|
||||
finally
|
||||
{
|
||||
GValue.Unset(ref gvStruct);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static unsafe class GValueHacks
|
||||
{
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
[DllImport("libgobject-2.0.so.0", CallingConvention = CallingConvention.Cdecl,
|
||||
EntryPoint = "g_value_set_string")]
|
||||
internal static extern void SetString(ref GValue.Struct value, byte* vString);
|
||||
}
|
||||
34
src/Oh.My.Stitcher/NetVips/OperationHacks.cs
Normal file
34
src/Oh.My.Stitcher/NetVips/OperationHacks.cs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
using NetVips;
|
||||
using NetVips.Internal;
|
||||
using VipsObject = NetVips.Internal.VipsObject;
|
||||
|
||||
namespace Oh.My.Stitcher.NetVips;
|
||||
|
||||
public static class OperationHacks
|
||||
{
|
||||
public static object Call(string operationName, ReadOnlySpan<byte> arg)
|
||||
{
|
||||
var intro = Introspect.Get(operationName);
|
||||
if (intro.RequiredInput.Count != 1)
|
||||
throw new ArgumentException($"unable to call {operationName}");
|
||||
|
||||
nint vop;
|
||||
using( var op = Operation.NewFromName(operationName) )
|
||||
{
|
||||
Introspect.Argument requiredArg = intro.RequiredInput[0];
|
||||
GObjectHacks.SetProperty(op, requiredArg.Name, arg);
|
||||
vop = VipsOperation.Build(op);
|
||||
if (vop == IntPtr.Zero)
|
||||
{
|
||||
VipsObject.UnrefOutputs(op);
|
||||
throw new VipsException($"unable to call {operationName}");
|
||||
}
|
||||
}
|
||||
using (var op = new Operation(vop))
|
||||
{
|
||||
object? result = op.Get(intro.RequiredOutput[0].Name);
|
||||
VipsObject.UnrefOutputs(op);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue