vendoring NetVips
This commit is contained in:
parent
36a0f8d39c
commit
33e9d5f43a
41 changed files with 21749 additions and 0 deletions
49
vendor/NetVips/Cache.cs
vendored
Normal file
49
vendor/NetVips/Cache.cs
vendored
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
using NetVips.Internal;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A class around libvips' operation cache.
|
||||||
|
/// </summary>
|
||||||
|
public static class Cache
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the maximum number of operations libvips keeps in cache.
|
||||||
|
/// </summary>
|
||||||
|
public static int Max
|
||||||
|
{
|
||||||
|
get => Vips.CacheGetMax();
|
||||||
|
set => Vips.CacheSetMax(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the maximum amount of tracked memory allowed.
|
||||||
|
/// </summary>
|
||||||
|
public static ulong MaxMem
|
||||||
|
{
|
||||||
|
get => Vips.CacheGetMaxMem();
|
||||||
|
set => Vips.CacheSetMaxMem(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the maximum amount of tracked files allowed.
|
||||||
|
/// </summary>
|
||||||
|
public static int MaxFiles
|
||||||
|
{
|
||||||
|
get => Vips.CacheGetMaxFiles();
|
||||||
|
set => Vips.CacheSetMaxFiles(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the current number of operations in cache.
|
||||||
|
/// </summary>
|
||||||
|
public static int Size => Vips.CacheGetSize();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enable or disable libvips cache tracing.
|
||||||
|
/// </summary>
|
||||||
|
public static bool Trace
|
||||||
|
{
|
||||||
|
set => Vips.CacheSetTrace(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
32
vendor/NetVips/Connection.cs
vendored
Normal file
32
vendor/NetVips/Connection.cs
vendored
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The abstract base Connection class.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class Connection : VipsObject
|
||||||
|
{
|
||||||
|
/// <inheritdoc cref="GObject"/>
|
||||||
|
internal Connection(nint pointer) : base(pointer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the filename associated with a connection. Return <see langword="null"/> if there
|
||||||
|
/// is no associated file.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The filename associated with this connection or <see langword="null"/>.</returns>
|
||||||
|
public string GetFileName()
|
||||||
|
{
|
||||||
|
return Internal.VipsConnection.FileName(this).ToUtf8String();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make a human-readable name for a connection suitable for error
|
||||||
|
/// messages.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The human-readable name for this connection.</returns>
|
||||||
|
public string GetNick()
|
||||||
|
{
|
||||||
|
return Internal.VipsConnection.Nick(this).ToUtf8String();
|
||||||
|
}
|
||||||
|
}
|
||||||
1312
vendor/NetVips/Enums.cs
vendored
Normal file
1312
vendor/NetVips/Enums.cs
vendored
Normal file
File diff suppressed because it is too large
Load diff
289
vendor/NetVips/ExtensionMethods.cs
vendored
Normal file
289
vendor/NetVips/ExtensionMethods.cs
vendored
Normal file
|
|
@ -0,0 +1,289 @@
|
||||||
|
using System;
|
||||||
|
using System.Buffers;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using NetVips.Internal;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Useful extension methods that we use in our codebase.
|
||||||
|
/// </summary>
|
||||||
|
internal static class ExtensionMethods
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Removes the element with the specified key from the <see cref="VOption"/>
|
||||||
|
/// and retrieves the value to <paramref name="target"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="self">The <see cref="VOption"/> to remove from.</param>
|
||||||
|
/// <param name="key">>The key of the element to remove.</param>
|
||||||
|
/// <param name="target">The target to retrieve the value to.</param>
|
||||||
|
/// <returns><see langword="true"/> if the element is successfully removed; otherwise, <see langword="false"/>.</returns>
|
||||||
|
internal static bool Remove(this VOption self, string key, out object target)
|
||||||
|
{
|
||||||
|
self.TryGetValue(key, out target);
|
||||||
|
return self.Remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Merges 2 <see cref="VOption"/>s.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="self">The <see cref="VOption"/> to merge into.</param>
|
||||||
|
/// <param name="merge">The <see cref="VOption"/> to merge from.</param>
|
||||||
|
internal static void Merge(this VOption self, VOption merge)
|
||||||
|
{
|
||||||
|
foreach (var item in merge)
|
||||||
|
{
|
||||||
|
self[item.Key] = item.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call a libvips operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image">A <see cref="Image"/> used as guide.</param>
|
||||||
|
/// <param name="operationName">Operation name.</param>
|
||||||
|
/// <returns>A new object.</returns>
|
||||||
|
internal static object Call(this Image image, string operationName) =>
|
||||||
|
Operation.Call(operationName, null, image);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call a libvips operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image">A <see cref="Image"/> used as guide.</param>
|
||||||
|
/// <param name="operationName">Operation name.</param>
|
||||||
|
/// <param name="args">An arbitrary number and variety of arguments.</param>
|
||||||
|
/// <returns>A new object.</returns>
|
||||||
|
internal static object Call(this Image image, string operationName, params object[] args) =>
|
||||||
|
Operation.Call(operationName, null, image, args);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call a libvips operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image">A <see cref="Image"/> used as guide.</param>
|
||||||
|
/// <param name="operationName">Operation name.</param>
|
||||||
|
/// <param name="kwargs">Optional arguments.</param>
|
||||||
|
/// <returns>A new object.</returns>
|
||||||
|
internal static object Call(this Image image, string operationName, VOption kwargs) =>
|
||||||
|
Operation.Call(operationName, kwargs, image);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call a libvips operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image">A <see cref="Image"/> used as guide.</param>
|
||||||
|
/// <param name="operationName">Operation name.</param>
|
||||||
|
/// <param name="kwargs">Optional arguments.</param>
|
||||||
|
/// <param name="args">An arbitrary number and variety of arguments.</param>
|
||||||
|
/// <returns>A new object.</returns>
|
||||||
|
internal static object Call(this Image image, string operationName, VOption kwargs, params object[] args) =>
|
||||||
|
Operation.Call(operationName, kwargs, image, args);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Prepends <paramref name="image"/> to <paramref name="args"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="args">The <see cref="Image"/> array.</param>
|
||||||
|
/// <param name="image">The <see cref="Image"/> to prepend to <paramref name="args"/>.</param>
|
||||||
|
/// <returns>A new object array.</returns>
|
||||||
|
internal static object[] PrependImage<T>(this T[] args, Image image)
|
||||||
|
{
|
||||||
|
if (args == null)
|
||||||
|
{
|
||||||
|
return new object[] { image };
|
||||||
|
}
|
||||||
|
|
||||||
|
var newValues = new object[args.Length + 1];
|
||||||
|
newValues[0] = image;
|
||||||
|
Array.Copy(args, 0, newValues, 1, args.Length);
|
||||||
|
return newValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Marshals a GLib UTF8 char* to a managed string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="utf8Str">Pointer to the GLib string.</param>
|
||||||
|
/// <param name="freePtr">If set to <see langword="true"/>, free the GLib string.</param>
|
||||||
|
/// <param name="size">Size of the GLib string, use 0 to read until the null character.</param>
|
||||||
|
/// <returns>The managed string.</returns>
|
||||||
|
internal static string ToUtf8String(this nint utf8Str, bool freePtr = false, int size = 0)
|
||||||
|
{
|
||||||
|
if (utf8Str == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
while (Marshal.ReadByte(utf8Str, size) != 0)
|
||||||
|
{
|
||||||
|
++size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
if (freePtr)
|
||||||
|
{
|
||||||
|
GLib.GFree(utf8Str);
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bytes = ArrayPool<byte>.Shared.Rent(size);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Marshal.Copy(utf8Str, bytes, 0, size);
|
||||||
|
return Encoding.UTF8.GetString(bytes, 0, size);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
ArrayPool<byte>.Shared.Return(bytes);
|
||||||
|
if (freePtr)
|
||||||
|
{
|
||||||
|
GLib.GFree(utf8Str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert bytes to human readable format.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The number of bytes.</param>
|
||||||
|
/// <returns>The readable format of the bytes.</returns>
|
||||||
|
internal static string ToReadableBytes(this ulong value)
|
||||||
|
{
|
||||||
|
string[] sizeSuffixes = { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
decimal dValue = value;
|
||||||
|
while (Math.Round(dValue, 2) >= 1000)
|
||||||
|
{
|
||||||
|
dValue /= 1024;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $"{dValue:n2} {sizeSuffixes[i]}";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Negate all elements in an array.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="array">An array of doubles.</param>
|
||||||
|
/// <returns>The negated array.</returns>
|
||||||
|
internal static double[] Negate(this double[] array)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < array.Length; i++)
|
||||||
|
{
|
||||||
|
array[i] *= -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Negate all elements in an array.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// It will output an array of doubles instead of integers.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="array">An array of integers.</param>
|
||||||
|
/// <returns>The negated array.</returns>
|
||||||
|
internal static double[] Negate(this int[] array)
|
||||||
|
{
|
||||||
|
var doubles = new double[array.Length];
|
||||||
|
for (var i = 0; i < array.Length; i++)
|
||||||
|
{
|
||||||
|
ref var value = ref doubles[i];
|
||||||
|
value = array[i] * -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return doubles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invert all elements in an array.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="array">An array of doubles.</param>
|
||||||
|
/// <returns>The inverted array.</returns>
|
||||||
|
internal static double[] Invert(this double[] array)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < array.Length; i++)
|
||||||
|
{
|
||||||
|
array[i] = 1.0 / array[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invert all elements in an array.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// It will output an array of doubles instead of integers.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="array">An array of integers.</param>
|
||||||
|
/// <returns>The inverted array.</returns>
|
||||||
|
internal static double[] Invert(this int[] array)
|
||||||
|
{
|
||||||
|
var doubles = new double[array.Length];
|
||||||
|
for (var i = 0; i < array.Length; i++)
|
||||||
|
{
|
||||||
|
ref var value = ref doubles[i];
|
||||||
|
value = 1.0 / array[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return doubles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compatibility method to call loaders with the <see cref="Enums.FailOn"/> enum.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="options">The optional arguments for the loader.</param>
|
||||||
|
/// <param name="failOn">The optional <see cref="Enums.FailOn"/> parameter.</param>
|
||||||
|
internal static void AddFailOn(this VOption options, Enums.FailOn? failOn = null)
|
||||||
|
{
|
||||||
|
if (!failOn.HasValue)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NetVips.AtLeastLibvips(8, 12))
|
||||||
|
{
|
||||||
|
options.Add("fail_on", failOn);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// The deprecated "fail" param was at the highest sensitivity (>= warning),
|
||||||
|
// but for compat it would be more correct to set this to true only when
|
||||||
|
// a non-permissive enum is given (> none).
|
||||||
|
options.Add("fail", failOn > Enums.FailOn.None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Compatibility method to call savers with the <see cref="Enums.ForeignKeep"/> enum.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="options">The optional arguments for the saver.</param>
|
||||||
|
/// <param name="keep">The optional <see cref="Enums.ForeignKeep"/> parameter.</param>
|
||||||
|
/// <param name="isDzsave">Whether this operation is <see cref="Image.Dzsave"/>-like.</param>
|
||||||
|
internal static void AddForeignKeep(this VOption options, Enums.ForeignKeep? keep = null, bool isDzsave = false)
|
||||||
|
{
|
||||||
|
if (!keep.HasValue)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NetVips.AtLeastLibvips(8, 15))
|
||||||
|
{
|
||||||
|
options.Add(nameof(keep), keep);
|
||||||
|
}
|
||||||
|
else if (isDzsave)
|
||||||
|
{
|
||||||
|
options.Add("no_strip", keep != Enums.ForeignKeep.None);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
options.Add("strip", keep == Enums.ForeignKeep.None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
198
vendor/NetVips/GObject.cs
vendored
Normal file
198
vendor/NetVips/GObject.cs
vendored
Normal file
|
|
@ -0,0 +1,198 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using NetVips.Internal;
|
||||||
|
|
||||||
|
using GSignalMatchType = NetVips.Internal.Enums.GSignalMatchType;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Manage <see cref="Internal.GObject"/> lifetime.
|
||||||
|
/// </summary>
|
||||||
|
public class GObject : SafeHandle
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// We have to record all of the <see cref="SignalConnect{T}"/> delegates to
|
||||||
|
/// prevent them from being re-located or disposed of by the garbage collector.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// All recorded delegates are freed in <see cref="ReleaseDelegates"/>.
|
||||||
|
/// </remarks>
|
||||||
|
private readonly ICollection<GCHandle> _handles = new List<GCHandle>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Hint of how much native memory is actually occupied by the object.
|
||||||
|
/// </summary>
|
||||||
|
internal long MemoryPressure;
|
||||||
|
|
||||||
|
// Handy for debugging
|
||||||
|
// public static int NObjects;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="GObject"/> class
|
||||||
|
/// with the specified pointer to wrap around.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Wraps a GObject instance around an underlying GValue. When the
|
||||||
|
/// instance is garbage-collected, the underlying object is unreferenced.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="pointer">The pointer to wrap around.</param>
|
||||||
|
internal GObject(nint pointer) : base(IntPtr.Zero, true)
|
||||||
|
{
|
||||||
|
// record the pointer we were given to manage
|
||||||
|
SetHandle(pointer);
|
||||||
|
|
||||||
|
// NObjects++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Connects a callback function (<paramref name="callback"/>) to a signal on this object.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The callback will be triggered every time this signal is issued on this instance.
|
||||||
|
/// </remarks>
|
||||||
|
/// <typeparam name="T">The type of the callback to connect.</typeparam>
|
||||||
|
/// <param name="detailedSignal">A string of the form "signal-name::detail".</param>
|
||||||
|
/// <param name="callback">The callback to connect.</param>
|
||||||
|
/// <param name="data">Data to pass to handler calls.</param>
|
||||||
|
/// <returns>The handler id.</returns>
|
||||||
|
/// <exception cref="T:System.ArgumentException">If it failed to connect the signal.</exception>
|
||||||
|
public ulong SignalConnect<T>(string detailedSignal, T callback, nint data = default)
|
||||||
|
where T : notnull
|
||||||
|
{
|
||||||
|
// add a weak reference callback to ensure all handles are released on finalization
|
||||||
|
if (_handles.Count == 0)
|
||||||
|
{
|
||||||
|
GWeakNotify notify = ReleaseDelegates;
|
||||||
|
var notifyHandle = GCHandle.Alloc(notify);
|
||||||
|
|
||||||
|
Internal.GObject.WeakRef(this, notify, GCHandle.ToIntPtr(notifyHandle));
|
||||||
|
}
|
||||||
|
|
||||||
|
// prevent the delegate from being re-located or disposed of by the garbage collector
|
||||||
|
var delegateHandle = GCHandle.Alloc(callback);
|
||||||
|
_handles.Add(delegateHandle);
|
||||||
|
|
||||||
|
var cHandler = Marshal.GetFunctionPointerForDelegate(callback);
|
||||||
|
var ret = GSignal.ConnectData(this, detailedSignal, cHandler, data, null, default);
|
||||||
|
if (ret == 0)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Failed to connect signal " + detailedSignal);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disconnects a handler from this object.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If the <paramref name="handlerId"/> is 0 then this function does nothing.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="handlerId">Handler id of the handler to be disconnected.</param>
|
||||||
|
public void SignalHandlerDisconnect(ulong handlerId)
|
||||||
|
{
|
||||||
|
if (handlerId != 0)
|
||||||
|
{
|
||||||
|
GSignal.HandlerDisconnect(this, handlerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disconnects all handlers from this object that match <paramref name="func"/> and
|
||||||
|
/// <paramref name="data"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">The type of the func.</typeparam>
|
||||||
|
/// <param name="func">The func of the handlers.</param>
|
||||||
|
/// <param name="data">The data of the handlers.</param>
|
||||||
|
/// <returns>The number of handlers that matched.</returns>
|
||||||
|
public uint SignalHandlersDisconnectByFunc<T>(T func, nint data = default)
|
||||||
|
where T : notnull
|
||||||
|
{
|
||||||
|
var funcPtr = Marshal.GetFunctionPointerForDelegate(func);
|
||||||
|
return GSignal.HandlersDisconnectMatched(this,
|
||||||
|
GSignalMatchType.G_SIGNAL_MATCH_FUNC | GSignalMatchType.G_SIGNAL_MATCH_DATA,
|
||||||
|
0, 0, IntPtr.Zero, funcPtr, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disconnects all handlers from this object that match <paramref name="data"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">The data of the handlers.</param>
|
||||||
|
/// <returns>The number of handlers that matched.</returns>
|
||||||
|
public uint SignalHandlersDisconnectByData(nint data)
|
||||||
|
{
|
||||||
|
return GSignal.HandlersDisconnectMatched(this,
|
||||||
|
GSignalMatchType.G_SIGNAL_MATCH_DATA,
|
||||||
|
0, 0, IntPtr.Zero, IntPtr.Zero, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decreases the reference count of object.
|
||||||
|
/// When its reference count drops to 0, the object is finalized (i.e. its memory is freed).
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><see langword="true"/> if the handle is released successfully; otherwise,
|
||||||
|
/// in the event of a catastrophic failure, <see langword="false"/>.</returns>
|
||||||
|
protected override bool ReleaseHandle()
|
||||||
|
{
|
||||||
|
if (!IsInvalid)
|
||||||
|
{
|
||||||
|
Internal.GObject.Unref(handle);
|
||||||
|
}
|
||||||
|
// NObjects--;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Release all the <see cref="SignalConnect{T}"/> delegates by this object on finalization.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This function is only called when <see cref="SignalConnect{T}"/> was used on this object.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="data">Data that was provided when the weak reference was established.</param>
|
||||||
|
/// <param name="objectPointer">The object being disposed.</param>
|
||||||
|
internal void ReleaseDelegates(nint data, nint objectPointer)
|
||||||
|
{
|
||||||
|
foreach (var gcHandle in _handles)
|
||||||
|
{
|
||||||
|
if (gcHandle.IsAllocated)
|
||||||
|
{
|
||||||
|
gcHandle.Free();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// All GCHandles are free'd. Clear the list to prevent inadvertent use.
|
||||||
|
_handles.Clear();
|
||||||
|
|
||||||
|
// Free the GCHandle used by this GWeakNotify
|
||||||
|
var notifyHandle = GCHandle.FromIntPtr(data);
|
||||||
|
if (notifyHandle.IsAllocated)
|
||||||
|
{
|
||||||
|
notifyHandle.Free();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Increases the reference count of object.
|
||||||
|
/// </summary>
|
||||||
|
internal nint ObjectRef()
|
||||||
|
{
|
||||||
|
return Internal.GObject.Ref(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the handle is invalid.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><see langword="true"/> if the handle is not valid; otherwise, <see langword="false"/>.</returns>
|
||||||
|
public override bool IsInvalid => handle == IntPtr.Zero;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the reference count of object. Handy for debugging.
|
||||||
|
/// </summary>
|
||||||
|
internal uint RefCount => Marshal.PtrToStructure<Internal.GObject.Struct>(handle).RefCount;
|
||||||
|
|
||||||
|
// Do not provide a finalizer - SafeHandle's critical finalizer will
|
||||||
|
// call ReleaseHandle for us.
|
||||||
|
}
|
||||||
513
vendor/NetVips/GValue.cs
vendored
Normal file
513
vendor/NetVips/GValue.cs
vendored
Normal file
|
|
@ -0,0 +1,513 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using NetVips.Internal;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wrap <see cref="Internal.GValue"/> in a C# class.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This class wraps <see cref="Internal.GValue"/> in a convenient interface. You can use
|
||||||
|
/// instances of this class to get and set <see cref="GObject"/> properties.
|
||||||
|
///
|
||||||
|
/// On construction, <see cref="Internal.GValue"/> is all zero (empty). You can pass it to
|
||||||
|
/// a get function to have it filled by <see cref="GObject"/>, or use init to
|
||||||
|
/// set a type, set to set a value, then use it to set an object property.
|
||||||
|
///
|
||||||
|
/// GValue lifetime is managed automatically.
|
||||||
|
/// </remarks>
|
||||||
|
public class GValue : IDisposable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The specified struct to wrap around.
|
||||||
|
/// </summary>
|
||||||
|
internal Internal.GValue.Struct Struct;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Track whether <see cref="O:Dispose"/> has been called.
|
||||||
|
/// </summary>
|
||||||
|
private bool _disposed;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Shift value used in converting numbers to type IDs.
|
||||||
|
/// </summary>
|
||||||
|
private const int FundamentalShift = 2;
|
||||||
|
|
||||||
|
// look up some common gtypes at init for speed
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type corresponding to gboolean.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint GBoolType = 5 << FundamentalShift;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type corresponding to gint.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint GIntType = 6 << FundamentalShift;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type corresponding to guint64.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint GUint64Type = 11 << FundamentalShift;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type from which all enumeration types are derived.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint GEnumType = 12 << FundamentalShift;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type from which all flags types are derived.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint GFlagsType = 13 << FundamentalShift;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type corresponding to gdouble.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint GDoubleType = 15 << FundamentalShift;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type corresponding to null-terminated C strings.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint GStrType = 16 << FundamentalShift;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type for GObject.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint GObjectType = 20 << FundamentalShift;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type for VipsImage.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint ImageType = NetVips.TypeFromName("VipsImage");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type for VipsArrayInt.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint ArrayIntType = NetVips.TypeFromName("VipsArrayInt");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type for VipsArrayDouble.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint ArrayDoubleType = NetVips.TypeFromName("VipsArrayDouble");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type for VipsArrayImage.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint ArrayImageType = NetVips.TypeFromName("VipsArrayImage");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type for VipsRefString.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint RefStrType = NetVips.TypeFromName("VipsRefString");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type for VipsBlob.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint BlobType = NetVips.TypeFromName("VipsBlob");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type for VipsBlendMode. See <see cref="Enums.BlendMode"/>.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint BlendModeType;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type for VipsSource. See <see cref="Source"/>.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint SourceType;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The fundamental type for VipsTarget. See <see cref="Target"/>.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly nint TargetType;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Hint of how much native memory is actually occupied by the object.
|
||||||
|
/// </summary>
|
||||||
|
private long _memoryPressure;
|
||||||
|
|
||||||
|
static GValue()
|
||||||
|
{
|
||||||
|
if (NetVips.AtLeastLibvips(8, 6))
|
||||||
|
{
|
||||||
|
BlendModeType = Vips.BlendModeGetType();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NetVips.AtLeastLibvips(8, 9))
|
||||||
|
{
|
||||||
|
SourceType = NetVips.TypeFromName("VipsSource");
|
||||||
|
TargetType = NetVips.TypeFromName("VipsTarget");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="GValue"/> class.
|
||||||
|
/// </summary>
|
||||||
|
public GValue()
|
||||||
|
{
|
||||||
|
Struct = new Internal.GValue.Struct();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="GValue"/> class
|
||||||
|
/// with the specified struct to wrap around.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The specified struct to wrap around.</param>
|
||||||
|
internal GValue(Internal.GValue.Struct value)
|
||||||
|
{
|
||||||
|
Struct = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the type of a GValue.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// GValues have a set type, fixed at creation time. Use SetType to set
|
||||||
|
/// the type of a GValue before assigning to it.
|
||||||
|
///
|
||||||
|
/// GTypes are 32 or 64-bit integers (depending on the platform). See
|
||||||
|
/// TypeFind.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="gtype">Type the GValue should hold values of.</param>
|
||||||
|
public void SetType(nint gtype)
|
||||||
|
{
|
||||||
|
Internal.GValue.Init(ref Struct, gtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ensure that the GC knows the true cost of the object during collection.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If the object is actually bigger than the managed size reflects, it may
|
||||||
|
/// be a candidate for quick(er) collection.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="bytesAllocated">The amount of unmanaged memory that has been allocated.</param>
|
||||||
|
private void AddMemoryPressure(long bytesAllocated)
|
||||||
|
{
|
||||||
|
if (bytesAllocated <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GC.AddMemoryPressure(bytesAllocated);
|
||||||
|
_memoryPressure += bytesAllocated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set a GValue.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The value is converted to the type of the GValue, if possible, and
|
||||||
|
/// assigned.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="value">Value to be set.</param>
|
||||||
|
public void Set(object value)
|
||||||
|
{
|
||||||
|
var gtype = GetTypeOf();
|
||||||
|
var fundamental = GType.Fundamental(gtype);
|
||||||
|
if (gtype == GBoolType)
|
||||||
|
{
|
||||||
|
Internal.GValue.SetBoolean(ref Struct, Convert.ToBoolean(value));
|
||||||
|
}
|
||||||
|
else if (gtype == GIntType)
|
||||||
|
{
|
||||||
|
Internal.GValue.SetInt(ref Struct, Convert.ToInt32(value));
|
||||||
|
}
|
||||||
|
else if (gtype == GUint64Type)
|
||||||
|
{
|
||||||
|
Internal.GValue.SetUint64(ref Struct, Convert.ToUInt64(value));
|
||||||
|
}
|
||||||
|
else if (gtype == GDoubleType)
|
||||||
|
{
|
||||||
|
Internal.GValue.SetDouble(ref Struct, Convert.ToDouble(value));
|
||||||
|
}
|
||||||
|
else if (fundamental == GEnumType)
|
||||||
|
{
|
||||||
|
Internal.GValue.SetEnum(ref Struct, Convert.ToInt32(value));
|
||||||
|
}
|
||||||
|
else if (fundamental == GFlagsType)
|
||||||
|
{
|
||||||
|
Internal.GValue.SetFlags(ref Struct, Convert.ToUInt32(value));
|
||||||
|
}
|
||||||
|
else if (gtype == GStrType)
|
||||||
|
{
|
||||||
|
var bytes = Encoding.UTF8.GetBytes(Convert.ToString(value) +
|
||||||
|
char.MinValue); // Ensure null-terminated string
|
||||||
|
Internal.GValue.SetString(ref Struct, bytes);
|
||||||
|
}
|
||||||
|
else if (gtype == RefStrType)
|
||||||
|
{
|
||||||
|
var bytes = Encoding.UTF8.GetBytes(Convert.ToString(value) +
|
||||||
|
char.MinValue); // Ensure null-terminated string
|
||||||
|
VipsValue.SetRefString(ref Struct, bytes);
|
||||||
|
}
|
||||||
|
else if (fundamental == GObjectType && value is GObject gObject)
|
||||||
|
{
|
||||||
|
AddMemoryPressure(gObject.MemoryPressure);
|
||||||
|
Internal.GValue.SetObject(ref Struct, gObject);
|
||||||
|
}
|
||||||
|
else if (gtype == ArrayIntType)
|
||||||
|
{
|
||||||
|
if (value is not IEnumerable)
|
||||||
|
{
|
||||||
|
value = new[] { value };
|
||||||
|
}
|
||||||
|
|
||||||
|
var integers = value switch
|
||||||
|
{
|
||||||
|
int[] ints => ints,
|
||||||
|
double[] doubles => Array.ConvertAll(doubles, Convert.ToInt32),
|
||||||
|
object[] objects => Array.ConvertAll(objects, Convert.ToInt32),
|
||||||
|
_ => throw new ArgumentException(
|
||||||
|
$"unsupported value type {value.GetType()} for gtype {NetVips.TypeName(gtype)}")
|
||||||
|
};
|
||||||
|
|
||||||
|
VipsValue.SetArrayInt(ref Struct, integers, integers.Length);
|
||||||
|
}
|
||||||
|
else if (gtype == ArrayDoubleType)
|
||||||
|
{
|
||||||
|
if (value is not IEnumerable)
|
||||||
|
{
|
||||||
|
value = new[] { value };
|
||||||
|
}
|
||||||
|
|
||||||
|
var doubles = value switch
|
||||||
|
{
|
||||||
|
double[] dbls => dbls,
|
||||||
|
int[] ints => Array.ConvertAll(ints, Convert.ToDouble),
|
||||||
|
object[] objects => Array.ConvertAll(objects, Convert.ToDouble),
|
||||||
|
_ => throw new ArgumentException(
|
||||||
|
$"unsupported value type {value.GetType()} for gtype {NetVips.TypeName(gtype)}")
|
||||||
|
};
|
||||||
|
|
||||||
|
VipsValue.SetArrayDouble(ref Struct, doubles, doubles.Length);
|
||||||
|
}
|
||||||
|
else if (gtype == ArrayImageType && value is Image[] images)
|
||||||
|
{
|
||||||
|
var size = images.Length;
|
||||||
|
VipsValue.SetArrayImage(ref Struct, size);
|
||||||
|
|
||||||
|
var ptrArr = VipsValue.GetArrayImage(in Struct, out _);
|
||||||
|
|
||||||
|
for (var i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
ref var image = ref images[i];
|
||||||
|
|
||||||
|
// the gvalue needs a ref on each of the images
|
||||||
|
Marshal.WriteIntPtr(ptrArr, i * IntPtr.Size, image.ObjectRef());
|
||||||
|
|
||||||
|
AddMemoryPressure(image.MemoryPressure);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (gtype == BlobType && value is VipsBlob blob)
|
||||||
|
{
|
||||||
|
AddMemoryPressure((long)blob.Length);
|
||||||
|
Internal.GValue.SetBoxed(ref Struct, blob);
|
||||||
|
}
|
||||||
|
else if (gtype == BlobType)
|
||||||
|
{
|
||||||
|
var memory = value switch
|
||||||
|
{
|
||||||
|
string strValue => Encoding.UTF8.GetBytes(strValue),
|
||||||
|
char[] charArrValue => Encoding.UTF8.GetBytes(charArrValue),
|
||||||
|
byte[] byteArrValue => byteArrValue,
|
||||||
|
_ => throw new ArgumentException(
|
||||||
|
$"unsupported value type {value.GetType()} for gtype {NetVips.TypeName(gtype)}")
|
||||||
|
};
|
||||||
|
|
||||||
|
// We need to set the blob to a copy of the string that vips can own
|
||||||
|
var ptr = GLib.GMalloc((ulong)memory.Length);
|
||||||
|
Marshal.Copy(memory, 0, ptr, memory.Length);
|
||||||
|
|
||||||
|
AddMemoryPressure(memory.Length);
|
||||||
|
|
||||||
|
if (NetVips.AtLeastLibvips(8, 6))
|
||||||
|
{
|
||||||
|
VipsValue.SetBlobFree(ref Struct, ptr, (ulong)memory.Length);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int FreeFn(nint a, nint b)
|
||||||
|
{
|
||||||
|
GLib.GFree(a);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
VipsValue.SetBlob(ref Struct, FreeFn, ptr, (ulong)memory.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
$"unsupported gtype for set {NetVips.TypeName(gtype)}, fundamental {NetVips.TypeName(fundamental)}, value type {value.GetType()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the contents of a GValue.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The contents of the GValue are read out as a C# type.
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns>The contents of this GValue.</returns>
|
||||||
|
public object Get()
|
||||||
|
{
|
||||||
|
var gtype = GetTypeOf();
|
||||||
|
var fundamental = GType.Fundamental(gtype);
|
||||||
|
|
||||||
|
object result;
|
||||||
|
if (gtype == GBoolType)
|
||||||
|
{
|
||||||
|
result = Internal.GValue.GetBoolean(in Struct);
|
||||||
|
}
|
||||||
|
else if (gtype == GIntType)
|
||||||
|
{
|
||||||
|
result = Internal.GValue.GetInt(in Struct);
|
||||||
|
}
|
||||||
|
else if (gtype == GUint64Type)
|
||||||
|
{
|
||||||
|
result = Internal.GValue.GetUint64(in Struct);
|
||||||
|
}
|
||||||
|
else if (gtype == GDoubleType)
|
||||||
|
{
|
||||||
|
result = Internal.GValue.GetDouble(in Struct);
|
||||||
|
}
|
||||||
|
else if (fundamental == GEnumType)
|
||||||
|
{
|
||||||
|
result = Internal.GValue.GetEnum(in Struct);
|
||||||
|
}
|
||||||
|
else if (fundamental == GFlagsType)
|
||||||
|
{
|
||||||
|
result = Internal.GValue.GetFlags(in Struct);
|
||||||
|
}
|
||||||
|
else if (gtype == GStrType)
|
||||||
|
{
|
||||||
|
result = Internal.GValue.GetString(in Struct).ToUtf8String();
|
||||||
|
}
|
||||||
|
else if (gtype == RefStrType)
|
||||||
|
{
|
||||||
|
result = VipsValue.GetRefString(in Struct, out var size).ToUtf8String(size: (int)size);
|
||||||
|
}
|
||||||
|
else if (gtype == ImageType)
|
||||||
|
{
|
||||||
|
// g_value_get_object() will not add a ref ... that is
|
||||||
|
// held by the gvalue
|
||||||
|
var vi = Internal.GValue.GetObject(in Struct);
|
||||||
|
|
||||||
|
// we want a ref that will last with the life of the vimage:
|
||||||
|
// this ref is matched by the unref that's attached to finalize
|
||||||
|
// by GObject
|
||||||
|
var image = new Image(vi);
|
||||||
|
image.ObjectRef();
|
||||||
|
|
||||||
|
result = image;
|
||||||
|
}
|
||||||
|
else if (gtype == ArrayIntType)
|
||||||
|
{
|
||||||
|
var intPtr = VipsValue.GetArrayInt(in Struct, out var size);
|
||||||
|
|
||||||
|
var intArr = new int[size];
|
||||||
|
Marshal.Copy(intPtr, intArr, 0, size);
|
||||||
|
result = intArr;
|
||||||
|
}
|
||||||
|
else if (gtype == ArrayDoubleType)
|
||||||
|
{
|
||||||
|
var intPtr = VipsValue.GetArrayDouble(in Struct, out var size);
|
||||||
|
|
||||||
|
var doubleArr = new double[size];
|
||||||
|
Marshal.Copy(intPtr, doubleArr, 0, size);
|
||||||
|
result = doubleArr;
|
||||||
|
}
|
||||||
|
else if (gtype == ArrayImageType)
|
||||||
|
{
|
||||||
|
var ptrArr = VipsValue.GetArrayImage(in Struct, out var size);
|
||||||
|
|
||||||
|
var images = new Image[size];
|
||||||
|
for (var i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
var vi = Marshal.ReadIntPtr(ptrArr, i * IntPtr.Size);
|
||||||
|
ref var image = ref images[i];
|
||||||
|
image = new Image(vi);
|
||||||
|
image.ObjectRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
result = images;
|
||||||
|
}
|
||||||
|
else if (gtype == BlobType)
|
||||||
|
{
|
||||||
|
var array = VipsValue.GetBlob(in Struct, out var size);
|
||||||
|
|
||||||
|
// Blob types are returned as an array of bytes.
|
||||||
|
var byteArr = new byte[size];
|
||||||
|
Marshal.Copy(array, byteArr, 0, (int)size);
|
||||||
|
result = byteArr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"unsupported gtype for get {NetVips.TypeName(gtype)}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the GType of this GValue.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The GType of this GValue.</returns>
|
||||||
|
public nint GetTypeOf()
|
||||||
|
{
|
||||||
|
return Struct.GType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finalizes an instance of the <see cref="GValue"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Allows an object to try to free resources and perform other cleanup
|
||||||
|
/// operations before it is reclaimed by garbage collection.
|
||||||
|
/// </remarks>
|
||||||
|
~GValue()
|
||||||
|
{
|
||||||
|
// Do not re-create Dispose clean-up code here.
|
||||||
|
Dispose(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Releases unmanaged and - optionally - managed resources.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="disposing"><see langword="true"/> to release both managed and unmanaged resources;
|
||||||
|
/// <see langword="false"/> to release only unmanaged resources.</param>
|
||||||
|
protected void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
// Check to see if Dispose has already been called.
|
||||||
|
if (!_disposed)
|
||||||
|
{
|
||||||
|
// and tag it to be unset on GC as well
|
||||||
|
Internal.GValue.Unset(ref Struct);
|
||||||
|
|
||||||
|
if (_memoryPressure > 0)
|
||||||
|
{
|
||||||
|
GC.RemoveMemoryPressure(_memoryPressure);
|
||||||
|
_memoryPressure = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note disposing has been done.
|
||||||
|
_disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Performs application-defined tasks associated with freeing, releasing,
|
||||||
|
/// or resetting unmanaged resources.
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Dispose(true);
|
||||||
|
|
||||||
|
// This object will be cleaned up by the Dispose method.
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
11770
vendor/NetVips/Image.Generated.cs
vendored
Normal file
11770
vendor/NetVips/Image.Generated.cs
vendored
Normal file
File diff suppressed because it is too large
Load diff
870
vendor/NetVips/Image.Operators.cs
vendored
Normal file
870
vendor/NetVips/Image.Operators.cs
vendored
Normal file
|
|
@ -0,0 +1,870 @@
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
public partial class Image
|
||||||
|
{
|
||||||
|
#region auto-generated operator overloads
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> + <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator +(Image left, Image right) =>
|
||||||
|
left.Call("add", right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> + <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double constant.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator +(double left, Image right) =>
|
||||||
|
right.Call("linear", 1.0, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> + <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double constant.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator +(Image left, double right) =>
|
||||||
|
left.Call("linear", 1.0, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> + <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator +(double[] left, Image right) =>
|
||||||
|
right.Call("linear", 1.0, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> + <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator +(Image left, double[] right) =>
|
||||||
|
left.Call("linear", 1.0, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> + <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left integer array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator +(int[] left, Image right) =>
|
||||||
|
right.Call("linear", 1.0, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> + <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right integer array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator +(Image left, int[] right) =>
|
||||||
|
left.Call("linear", 1.0, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> - <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator -(Image left, Image right) =>
|
||||||
|
left.Call("subtract", right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> - <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double constant.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator -(double left, Image right) =>
|
||||||
|
right.Call("linear", -1.0, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> - <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double constant.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator -(Image left, double right) =>
|
||||||
|
left.Call("linear", 1.0, -right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> - <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator -(double[] left, Image right) =>
|
||||||
|
right.Call("linear", -1.0, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> - <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator -(Image left, double[] right) =>
|
||||||
|
left.Call("linear", 1.0, right.Negate()) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> - <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left integer array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator -(int[] left, Image right) =>
|
||||||
|
right.Call("linear", -1.0, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> - <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right integer array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator -(Image left, int[] right) =>
|
||||||
|
left.Call("linear", 1.0, right.Negate()) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> * <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator *(Image left, Image right) =>
|
||||||
|
left.Call("multiply", right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> * <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double constant.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator *(double left, Image right) =>
|
||||||
|
right.Call("linear", left, 0.0) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> * <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double constant.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator *(Image left, double right) =>
|
||||||
|
left.Call("linear", right, 0.0) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> * <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator *(double[] left, Image right) =>
|
||||||
|
right.Call("linear", left, 0.0) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> * <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator *(Image left, double[] right) =>
|
||||||
|
left.Call("linear", right, 0.0) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> * <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left integer array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator *(int[] left, Image right) =>
|
||||||
|
right.Call("linear", left, 0.0) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> * <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right integer array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator *(Image left, int[] right) =>
|
||||||
|
left.Call("linear", right, 0.0) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> / <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator /(Image left, Image right) =>
|
||||||
|
left.Call("divide", right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> / <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double constant.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator /(double left, Image right) =>
|
||||||
|
right.Pow(-1.0).Call("linear", left, 0.0) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> / <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double constant.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator /(Image left, double right) =>
|
||||||
|
left.Call("linear", 1.0 / right, 0.0) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> / <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator /(double[] left, Image right) =>
|
||||||
|
right.Pow(-1.0).Call("linear", left, 0.0) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> / <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator /(Image left, double[] right) =>
|
||||||
|
left.Call("linear", right.Invert(), 0.0) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> / <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left integer array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator /(int[] left, Image right) =>
|
||||||
|
right.Pow(-1.0).Call("linear", left, 0.0) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> / <paramref name="right"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right integer array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator /(Image left, int[] right) =>
|
||||||
|
left.Call("linear", right.Invert(), 0.0) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> % <paramref name="right"/>
|
||||||
|
/// (remainder after integer division).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator %(Image left, Image right) =>
|
||||||
|
left.Call("remainder", right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> % <paramref name="right"/>
|
||||||
|
/// (remainder after integer division).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double constant.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator %(double left, Image right) =>
|
||||||
|
right.Call("remainder_const", left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> % <paramref name="right"/>
|
||||||
|
/// (remainder after integer division).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double constant.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator %(Image left, double right) =>
|
||||||
|
left.Call("remainder_const", right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> % <paramref name="right"/>
|
||||||
|
/// (remainder after integer division).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator %(double[] left, Image right) =>
|
||||||
|
right.Call("remainder_const", left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> % <paramref name="right"/>
|
||||||
|
/// (remainder after integer division).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator %(Image left, double[] right) =>
|
||||||
|
left.Call("remainder_const", right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> % <paramref name="right"/>
|
||||||
|
/// (remainder after integer division).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left integer array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator %(int[] left, Image right) =>
|
||||||
|
right.Call("remainder_const", left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation calculates <paramref name="left"/> % <paramref name="right"/>
|
||||||
|
/// (remainder after integer division).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right integer array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator %(Image left, int[] right) =>
|
||||||
|
left.Call("remainder_const", right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the logical bitwise AND of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator &(Image left, Image right) =>
|
||||||
|
left.Call("boolean", right, Enums.OperationBoolean.And) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the logical bitwise AND of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double constant.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator &(double left, Image right) =>
|
||||||
|
right.Call("boolean_const", Enums.OperationBoolean.And, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the logical bitwise AND of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double constant.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator &(Image left, double right) =>
|
||||||
|
left.Call("boolean_const", Enums.OperationBoolean.And, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the logical bitwise AND of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator &(double[] left, Image right) =>
|
||||||
|
right.Call("boolean_const", Enums.OperationBoolean.And, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the logical bitwise AND of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator &(Image left, double[] right) =>
|
||||||
|
left.Call("boolean_const", Enums.OperationBoolean.And, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the logical bitwise AND of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left integer array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator &(int[] left, Image right) =>
|
||||||
|
right.Call("boolean_const", Enums.OperationBoolean.And, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the logical bitwise AND of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right integer array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator &(Image left, int[] right) =>
|
||||||
|
left.Call("boolean_const", Enums.OperationBoolean.And, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the bitwise OR of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator |(Image left, Image right) =>
|
||||||
|
left.Call("boolean", right, Enums.OperationBoolean.Or) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the bitwise OR of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double constant.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator |(double left, Image right) =>
|
||||||
|
right.Call("boolean_const", Enums.OperationBoolean.Or, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the bitwise OR of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double constant.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator |(Image left, double right) =>
|
||||||
|
left.Call("boolean_const", Enums.OperationBoolean.Or, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the bitwise OR of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator |(double[] left, Image right) =>
|
||||||
|
right.Call("boolean_const", Enums.OperationBoolean.Or, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the bitwise OR of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator |(Image left, double[] right) =>
|
||||||
|
left.Call("boolean_const", Enums.OperationBoolean.Or, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the bitwise OR of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left integer array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator |(int[] left, Image right) =>
|
||||||
|
right.Call("boolean_const", Enums.OperationBoolean.Or, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the bitwise OR of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right integer array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator |(Image left, int[] right) =>
|
||||||
|
left.Call("boolean_const", Enums.OperationBoolean.Or, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the bitwise exclusive-OR of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator ^(Image left, Image right) =>
|
||||||
|
left.Call("boolean", right, Enums.OperationBoolean.Eor) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the bitwise exclusive-OR of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double constant.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator ^(double left, Image right) =>
|
||||||
|
right.Call("boolean_const", Enums.OperationBoolean.Eor, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the bitwise exclusive-OR of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double constant.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator ^(Image left, double right) =>
|
||||||
|
left.Call("boolean_const", Enums.OperationBoolean.Eor, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the bitwise exclusive-OR of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator ^(double[] left, Image right) =>
|
||||||
|
right.Call("boolean_const", Enums.OperationBoolean.Eor, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the bitwise exclusive-OR of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator ^(Image left, double[] right) =>
|
||||||
|
left.Call("boolean_const", Enums.OperationBoolean.Eor, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the bitwise exclusive-OR of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left integer array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator ^(int[] left, Image right) =>
|
||||||
|
right.Call("boolean_const", Enums.OperationBoolean.Eor, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation computes the bitwise exclusive-OR of its operands.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right integer array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator ^(Image left, int[] right) =>
|
||||||
|
left.Call("boolean_const", Enums.OperationBoolean.Eor, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation shifts its first operand left by the number of bits specified by its second operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">The number of bits.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator <<(Image left, int right) =>
|
||||||
|
left.Call("boolean_const", Enums.OperationBoolean.Lshift, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation shifts its first operand right by the number of bits specified by its second operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">The number of bits.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator >>(Image left, int right) =>
|
||||||
|
left.Call("boolean_const", Enums.OperationBoolean.Rshift, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares two images on equality.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double constant to compare.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/> to compare.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator ==(double left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.Equal, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares two images on equality.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double array to compare.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/> to compare.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator ==(double[] left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.Equal, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares two images on equality.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left integer array to compare.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/> to compare.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator ==(int[] left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.Equal, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares two images on inequality.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double constant to compare.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/> to compare.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator !=(double left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.Noteq, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares two images on inequality.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double array to compare.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/> to compare.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator !=(double[] left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.Noteq, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares two images on inequality.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left integer array to compare.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/> to compare.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator !=(int[] left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.Noteq, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is less than the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator <(Image left, Image right) =>
|
||||||
|
left.Call("relational", right, Enums.OperationRelational.Less) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is less than the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double constant.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator <(double left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.More, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is less than the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double constant.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator <(Image left, double right) =>
|
||||||
|
left.Call("relational_const", Enums.OperationRelational.Less, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is less than the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator <(double[] left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.More, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is less than the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator <(Image left, double[] right) =>
|
||||||
|
left.Call("relational_const", Enums.OperationRelational.Less, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is less than the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left integer array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator <(int[] left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.More, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is less than the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right integer array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator <(Image left, int[] right) =>
|
||||||
|
left.Call("relational_const", Enums.OperationRelational.Less, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is greater than the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator >(Image left, Image right) =>
|
||||||
|
left.Call("relational", right, Enums.OperationRelational.More) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is greater than the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double constant.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator >(double left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.Less, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is greater than the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double constant.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator >(Image left, double right) =>
|
||||||
|
left.Call("relational_const", Enums.OperationRelational.More, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is greater than the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator >(double[] left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.Less, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is greater than the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator >(Image left, double[] right) =>
|
||||||
|
left.Call("relational_const", Enums.OperationRelational.More, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is greater than the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left integer array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator >(int[] left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.Less, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is greater than the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right integer array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator >(Image left, int[] right) =>
|
||||||
|
left.Call("relational_const", Enums.OperationRelational.More, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is less than or equal to the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator <=(Image left, Image right) =>
|
||||||
|
left.Call("relational", right, Enums.OperationRelational.Lesseq) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is less than or equal to the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double constant.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator <=(double left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.Moreeq, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is less than or equal to the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double constant.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator <=(Image left, double right) =>
|
||||||
|
left.Call("relational_const", Enums.OperationRelational.Lesseq, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is less than or equal to the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator <=(double[] left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.Moreeq, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is less than or equal to the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator <=(Image left, double[] right) =>
|
||||||
|
left.Call("relational_const", Enums.OperationRelational.Lesseq, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is less than or equal to the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left integer array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator <=(int[] left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.Moreeq, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is less than or equal to the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right integer array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator <=(Image left, int[] right) =>
|
||||||
|
left.Call("relational_const", Enums.OperationRelational.Lesseq, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is greater than or equal to the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator >=(Image left, Image right) =>
|
||||||
|
left.Call("relational", right, Enums.OperationRelational.Moreeq) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is greater than or equal to the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double constant.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator >=(double left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.Lesseq, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is greater than or equal to the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double constant.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator >=(Image left, double right) =>
|
||||||
|
left.Call("relational_const", Enums.OperationRelational.Moreeq, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is greater than or equal to the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left double array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator >=(double[] left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.Lesseq, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is greater than or equal to the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right double array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator >=(Image left, double[] right) =>
|
||||||
|
left.Call("relational_const", Enums.OperationRelational.Moreeq, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is greater than or equal to the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left integer array.</param>
|
||||||
|
/// <param name="right">Right <see cref="Image"/>.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator >=(int[] left, Image right) =>
|
||||||
|
right.Call("relational_const", Enums.OperationRelational.Lesseq, left) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This operation compares if the left operand is greater than or equal to the right operand.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left <see cref="Image"/>.</param>
|
||||||
|
/// <param name="right">Right integer array.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
public static Image operator >=(Image left, int[] right) =>
|
||||||
|
left.Call("relational_const", Enums.OperationRelational.Moreeq, right) as Image;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a value indicating whether a given <see cref="Image"/> is definitely <see langword="true"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image">The image to check.</param>
|
||||||
|
/// <returns><see langword="true"/> if <paramref name="image"/> is definitely <see langword="true"/>; otherwise, <see langword="false"/>.</returns>
|
||||||
|
public static bool operator true(Image image) =>
|
||||||
|
// Always evaluate to false so that each side of the && equation is evaluated
|
||||||
|
false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns a value indicating whether a given <see cref="Image"/> is definitely <see langword="false"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image">The image to check.</param>
|
||||||
|
/// <returns><see langword="true"/> if <paramref name="image"/> is definitely <see langword="false"/>; otherwise, <see langword="false"/>.</returns>
|
||||||
|
public static bool operator false(Image image) =>
|
||||||
|
// Always evaluate to false so that each side of the && equation is evaluated
|
||||||
|
false;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
2328
vendor/NetVips/Image.cs
vendored
Normal file
2328
vendor/NetVips/Image.cs
vendored
Normal file
File diff suppressed because it is too large
Load diff
42
vendor/NetVips/Internal/Enums.cs
vendored
Normal file
42
vendor/NetVips/Internal/Enums.cs
vendored
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace NetVips.Internal;
|
||||||
|
|
||||||
|
internal static class Enums
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
internal enum GParamFlags
|
||||||
|
{
|
||||||
|
G_PARAM_READABLE = 1 << 0,
|
||||||
|
G_PARAM_WRITABLE = 1 << 1,
|
||||||
|
G_PARAM_READWRITE = G_PARAM_READABLE | G_PARAM_WRITABLE,
|
||||||
|
G_PARAM_CONSTRUCT = 1 << 2,
|
||||||
|
G_PARAM_CONSTRUCT_ONLY = 1 << 3,
|
||||||
|
G_PARAM_LAX_VALIDATION = 1 << 4,
|
||||||
|
G_PARAM_STATIC_NAME = 1 << 5,
|
||||||
|
G_PARAM_PRIVATE = G_PARAM_STATIC_NAME,
|
||||||
|
G_PARAM_STATIC_NICK = 1 << 6,
|
||||||
|
G_PARAM_STATIC_BLURB = 1 << 7,
|
||||||
|
G_PARAM_EXPLICIT_NOTIFY = 1 << 30,
|
||||||
|
G_PARAM_DEPRECATED = 1 << 31
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
internal enum GConnectFlags
|
||||||
|
{
|
||||||
|
G_CONNECT_DEFAULT = 0,
|
||||||
|
G_CONNECT_AFTER = 1 << 0,
|
||||||
|
G_CONNECT_SWAPPED = 1 << 1
|
||||||
|
}
|
||||||
|
|
||||||
|
[Flags]
|
||||||
|
internal enum GSignalMatchType
|
||||||
|
{
|
||||||
|
G_SIGNAL_MATCH_ID = 1 << 0,
|
||||||
|
G_SIGNAL_MATCH_DETAIL = 1 << 1,
|
||||||
|
G_SIGNAL_MATCH_CLOSURE = 1 << 2,
|
||||||
|
G_SIGNAL_MATCH_FUNC = 1 << 3,
|
||||||
|
G_SIGNAL_MATCH_DATA = 1 << 4,
|
||||||
|
G_SIGNAL_MATCH_UNBLOCKED = 1 << 5
|
||||||
|
}
|
||||||
|
}
|
||||||
47
vendor/NetVips/Internal/GLib.cs
vendored
Normal file
47
vendor/NetVips/Internal/GLib.cs
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security;
|
||||||
|
using NetVips.Interop;
|
||||||
|
|
||||||
|
using LogLevelFlags = NetVips.Enums.LogLevelFlags;
|
||||||
|
|
||||||
|
namespace NetVips.Internal;
|
||||||
|
|
||||||
|
internal static class GLib
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate void LogFuncNative([MarshalAs(UnmanagedType.LPStr)] string logDomain,
|
||||||
|
LogLevelFlags flags, nint message, nint userData);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GLib, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_free")]
|
||||||
|
internal static extern void GFree(nint mem);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GLib, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_malloc")]
|
||||||
|
internal static extern nint GMalloc(ulong nBytes);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GLib, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_log_set_handler")]
|
||||||
|
internal static extern uint GLogSetHandler([MarshalAs(UnmanagedType.LPStr)] string logDomain,
|
||||||
|
LogLevelFlags flags, LogFuncNative logFunc, nint userData);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GLib, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_log_remove_handler")]
|
||||||
|
internal static extern void
|
||||||
|
GLogRemoveHandler([MarshalAs(UnmanagedType.LPStr)] string logDomain, uint handlerId);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GLib, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_log_set_always_fatal")]
|
||||||
|
internal static extern LogLevelFlags GLogSetAlwaysFatal(LogLevelFlags fatalMask);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GLib, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_log_set_fatal_mask")]
|
||||||
|
internal static extern LogLevelFlags GLogSetFatalMask(
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)] string logDomain, LogLevelFlags fatalMask);
|
||||||
|
}
|
||||||
260
vendor/NetVips/Internal/GObject.cs
vendored
Normal file
260
vendor/NetVips/Internal/GObject.cs
vendored
Normal file
|
|
@ -0,0 +1,260 @@
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security;
|
||||||
|
using NetVips.Interop;
|
||||||
|
|
||||||
|
using GObjectManaged = NetVips.GObject;
|
||||||
|
using VipsBlobManaged = NetVips.VipsBlob;
|
||||||
|
|
||||||
|
namespace NetVips.Internal;
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate void GWeakNotify(nint data, nint objectPointer);
|
||||||
|
|
||||||
|
internal static class GObject
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct Struct
|
||||||
|
{
|
||||||
|
internal nint GTypeInstance;
|
||||||
|
|
||||||
|
internal uint RefCount;
|
||||||
|
|
||||||
|
internal nint QData;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_object_set_property")]
|
||||||
|
internal static extern void SetProperty(GObjectManaged @object,
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)] string propertyName, in GValue.Struct value);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_object_get_property")]
|
||||||
|
internal static extern void GetProperty(GObjectManaged @object,
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)] string propertyName, ref GValue.Struct value);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_object_ref")]
|
||||||
|
internal static extern nint Ref(nint @object);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_object_unref")]
|
||||||
|
internal static extern void Unref(nint @object);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_object_weak_ref")]
|
||||||
|
internal static extern void WeakRef(GObjectManaged @object, GWeakNotify notify, nint data);
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct GEnumValue
|
||||||
|
{
|
||||||
|
internal int Value;
|
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)]
|
||||||
|
internal string ValueName;
|
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)]
|
||||||
|
internal string ValueNick;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct GEnumClass
|
||||||
|
{
|
||||||
|
internal nint GTypeClass;
|
||||||
|
|
||||||
|
internal int Minimum;
|
||||||
|
internal int Maximum;
|
||||||
|
internal uint NValues;
|
||||||
|
|
||||||
|
internal nint Values;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class GType
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_type_name")]
|
||||||
|
internal static extern nint Name(nint type);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_type_from_name")]
|
||||||
|
internal static extern nint FromName([MarshalAs(UnmanagedType.LPStr)] string name);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_type_fundamental")]
|
||||||
|
internal static extern nint Fundamental(nint typeId);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_type_class_ref")]
|
||||||
|
internal static extern nint ClassRef(nint type);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class GValue
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Explicit, Size = 24)]
|
||||||
|
internal struct Struct
|
||||||
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
internal nint GType;
|
||||||
|
|
||||||
|
[FieldOffset(8)]
|
||||||
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
|
||||||
|
internal nint[] Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_init")]
|
||||||
|
internal static extern nint Init(ref Struct value, nint gType);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_unset")]
|
||||||
|
internal static extern void Unset(ref Struct value);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_set_boolean")]
|
||||||
|
internal static extern void SetBoolean(ref Struct value, [MarshalAs(UnmanagedType.Bool)] bool vBoolean);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_get_boolean")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static extern bool GetBoolean(in Struct value);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_set_int")]
|
||||||
|
internal static extern void SetInt(ref Struct value, int vInt);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_get_int")]
|
||||||
|
internal static extern int GetInt(in Struct value);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_set_uint64")]
|
||||||
|
internal static extern void SetUint64(ref Struct value, ulong vUint64);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_get_uint64")]
|
||||||
|
internal static extern ulong GetUint64(in Struct value);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_set_double")]
|
||||||
|
internal static extern void SetDouble(ref Struct value, double vDouble);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_get_double")]
|
||||||
|
internal static extern double GetDouble(in Struct value);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_set_string")]
|
||||||
|
internal static extern void SetString(ref Struct value, byte[] vString);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_get_string")]
|
||||||
|
internal static extern nint GetString(in Struct value);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_set_enum")]
|
||||||
|
internal static extern void SetEnum(ref Struct value, int vEnum);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_get_enum")]
|
||||||
|
internal static extern int GetEnum(in Struct value);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_set_flags")]
|
||||||
|
internal static extern void SetFlags(ref Struct value, uint vFlags);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_get_flags")]
|
||||||
|
internal static extern uint GetFlags(in Struct value);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_set_object")]
|
||||||
|
internal static extern void SetObject(ref Struct value, GObjectManaged vObject);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_get_object")]
|
||||||
|
internal static extern nint GetObject(in Struct value);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_value_set_boxed")]
|
||||||
|
internal static extern void SetBoxed(ref Struct value, VipsBlobManaged boxed);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class GParamSpec
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct Struct
|
||||||
|
{
|
||||||
|
internal nint GTypeInstance;
|
||||||
|
|
||||||
|
internal nint Name;
|
||||||
|
|
||||||
|
internal Enums.GParamFlags Flags;
|
||||||
|
internal nint ValueType;
|
||||||
|
internal nint OwnerType;
|
||||||
|
|
||||||
|
internal nint Nick;
|
||||||
|
internal nint Blurb;
|
||||||
|
internal nint QData;
|
||||||
|
internal uint RefCount;
|
||||||
|
internal uint ParamId;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_param_spec_get_blurb")]
|
||||||
|
internal static extern nint GetBlurb(in Struct pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate void GClosureNotify(nint data, nint closure);
|
||||||
|
|
||||||
|
internal static class GSignal
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_signal_connect_data")]
|
||||||
|
internal static extern ulong ConnectData(GObjectManaged instance,
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)] string detailedSignal,
|
||||||
|
nint cHandler, nint data,
|
||||||
|
GClosureNotify destroyData, Enums.GConnectFlags connectFlags);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_signal_handler_disconnect")]
|
||||||
|
internal static extern void HandlerDisconnect(GObjectManaged instance, ulong handlerId);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.GObject, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "g_signal_handlers_disconnect_matched")]
|
||||||
|
internal static extern uint HandlersDisconnectMatched(GObjectManaged instance,
|
||||||
|
Enums.GSignalMatchType mask, uint signalId, uint detail, nint closure,
|
||||||
|
nint func, nint data);
|
||||||
|
}
|
||||||
708
vendor/NetVips/Internal/Vips.cs
vendored
Normal file
708
vendor/NetVips/Internal/Vips.cs
vendored
Normal file
|
|
@ -0,0 +1,708 @@
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Security;
|
||||||
|
using System.Text;
|
||||||
|
using NetVips.Interop;
|
||||||
|
|
||||||
|
using ArgumentFlags = NetVips.Enums.ArgumentFlags;
|
||||||
|
using BandFormat = NetVips.Enums.BandFormat;
|
||||||
|
using OperationFlags = NetVips.Enums.OperationFlags;
|
||||||
|
using VipsBlobManaged = NetVips.VipsBlob;
|
||||||
|
using VipsObjectManaged = NetVips.VipsObject;
|
||||||
|
|
||||||
|
namespace NetVips.Internal;
|
||||||
|
|
||||||
|
internal static class Vips
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate nint TypeMap2Fn(nint type, nint a, nint b);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate nint ArgumentMapFn(nint @object, nint pspec, nint argumentClass,
|
||||||
|
nint argumentInstance, nint a, nint b);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate int CallbackFn(nint a, nint b);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_init")]
|
||||||
|
internal static extern int Init([MarshalAs(UnmanagedType.LPStr)] string argv0);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_shutdown")]
|
||||||
|
internal static extern void Shutdown();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_leak_set")]
|
||||||
|
internal static extern void LeakSet([MarshalAs(UnmanagedType.Bool)] bool leak);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_profile_set")]
|
||||||
|
internal static extern void ProfileSet([MarshalAs(UnmanagedType.Bool)] bool profile);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_cache_get_max")]
|
||||||
|
internal static extern int CacheGetMax();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_cache_set_max")]
|
||||||
|
internal static extern void CacheSetMax(int max);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_cache_get_max_mem")]
|
||||||
|
internal static extern nuint CacheGetMaxMem();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_cache_set_max_mem")]
|
||||||
|
internal static extern void CacheSetMaxMem(ulong maxMem);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_cache_get_max_files")]
|
||||||
|
internal static extern int CacheGetMaxFiles();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_cache_set_max_files")]
|
||||||
|
internal static extern void CacheSetMaxFiles(int maxFiles);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_cache_get_size")]
|
||||||
|
internal static extern int CacheGetSize();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_cache_set_trace")]
|
||||||
|
internal static extern void CacheSetTrace([MarshalAs(UnmanagedType.Bool)] bool trace);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_concurrency_set")]
|
||||||
|
internal static extern void ConcurrencySet(int concurrency);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_concurrency_get")]
|
||||||
|
internal static extern int ConcurrencyGet();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_vector_isenabled")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static extern bool VectorIsEnabled();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_vector_set_enabled")]
|
||||||
|
internal static extern void VectorSet([MarshalAs(UnmanagedType.Bool)] bool enabled);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_block_untrusted_set")]
|
||||||
|
internal static extern void BlockUntrustedSet([MarshalAs(UnmanagedType.Bool)] bool state);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_tracked_get_allocs")]
|
||||||
|
internal static extern int TrackedGetAllocs();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_tracked_get_mem")]
|
||||||
|
internal static extern int TrackedGetMem();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_tracked_get_files")]
|
||||||
|
internal static extern int TrackedGetFiles();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_tracked_get_mem_highwater")]
|
||||||
|
internal static extern ulong TrackedGetMemHighwater();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_version")]
|
||||||
|
internal static extern int Version(int flag);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_error_buffer")]
|
||||||
|
internal static extern nint ErrorBuffer();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_error_clear")]
|
||||||
|
internal static extern void ErrorClear();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_error_freeze")]
|
||||||
|
internal static extern void ErrorFreeze();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_error_thaw")]
|
||||||
|
internal static extern void ErrorThaw();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_path_filename7")]
|
||||||
|
internal static extern nint PathFilename7(byte[] path);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_path_mode7")]
|
||||||
|
internal static extern nint PathMode7(byte[] path);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_filename_get_filename")]
|
||||||
|
internal static extern nint GetFilename(byte[] vipsFilename);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_filename_get_options")]
|
||||||
|
internal static extern nint GetOptions(byte[] vipsFilename);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_blend_mode_get_type")]
|
||||||
|
internal static extern nint BlendModeGetType();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_interpretation_get_type")]
|
||||||
|
internal static extern nint InterpretationGetType();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_band_format_get_type")]
|
||||||
|
internal static extern nint BandFormatGetType();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_argument_map")]
|
||||||
|
internal static extern nint ArgumentMap(VipsObjectManaged @object, ArgumentMapFn fn, nint a,
|
||||||
|
nint b);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_type_map")]
|
||||||
|
internal static extern nint TypeMap(nint @base, TypeMap2Fn fn, nint a, nint b);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_type_find")]
|
||||||
|
internal static extern nint TypeFind([MarshalAs(UnmanagedType.LPStr)] string basename,
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)] string nickname);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_nickname_find")]
|
||||||
|
internal static extern nint NicknameFind(nint type);
|
||||||
|
|
||||||
|
internal static string PathFilename7(string path)
|
||||||
|
{
|
||||||
|
var bytes = Encoding.UTF8.GetBytes(path + char.MinValue); // Ensure null-terminated string
|
||||||
|
return PathFilename7(bytes).ToUtf8String();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static string PathMode7(string path)
|
||||||
|
{
|
||||||
|
var bytes = Encoding.UTF8.GetBytes(path + char.MinValue); // Ensure null-terminated string
|
||||||
|
return PathMode7(bytes).ToUtf8String();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class VipsObject
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl, EntryPoint = "vips_object_get_args")]
|
||||||
|
internal static extern int GetArgs(VipsObjectManaged @object, out nint names, out nint flags,
|
||||||
|
out int nArgs);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_object_get_argument")]
|
||||||
|
internal static extern int GetArgument(VipsObjectManaged @object,
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)] string name,
|
||||||
|
out nint pspec, out VipsArgumentClass argumentClass,
|
||||||
|
out VipsArgumentInstance argumentInstance);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_object_set_from_string")]
|
||||||
|
internal static extern int SetFromString(VipsObjectManaged @object,
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)] string @string);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl, EntryPoint = "vips_object_print_all")]
|
||||||
|
internal static extern void PrintAll();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_object_unref_outputs")]
|
||||||
|
internal static extern void UnrefOutputs(VipsObjectManaged @object);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_object_get_description")]
|
||||||
|
internal static extern nint GetDescription(VipsObjectManaged @object);
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct VipsArgumentClass
|
||||||
|
{
|
||||||
|
internal nint Parent;
|
||||||
|
internal nint ObjectClass;
|
||||||
|
internal ArgumentFlags Flags;
|
||||||
|
|
||||||
|
internal int Priority;
|
||||||
|
internal uint Offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct VipsArgumentInstance
|
||||||
|
{
|
||||||
|
internal nint Parent;
|
||||||
|
internal nint ArgumentClass;
|
||||||
|
internal nint Object;
|
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal bool Assigned;
|
||||||
|
internal uint CloseId;
|
||||||
|
internal uint InvalidateId;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class VipsBlob
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl, EntryPoint = "vips_blob_get")]
|
||||||
|
internal static extern nint Get(VipsBlobManaged blob, out nuint length);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl, EntryPoint = "vips_blob_copy")]
|
||||||
|
internal static extern unsafe nint Copy(void* data, nuint length);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class VipsArea
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct Struct
|
||||||
|
{
|
||||||
|
internal nint Data;
|
||||||
|
internal nuint Length;
|
||||||
|
|
||||||
|
internal int N;
|
||||||
|
|
||||||
|
// private
|
||||||
|
|
||||||
|
internal int Count;
|
||||||
|
internal nint Lock;
|
||||||
|
|
||||||
|
internal Vips.CallbackFn FreeFn;
|
||||||
|
internal nint Client;
|
||||||
|
|
||||||
|
internal nint Type;
|
||||||
|
internal nuint SizeofType;
|
||||||
|
}
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl, EntryPoint = "vips_area_unref")]
|
||||||
|
internal static extern nint Unref(nint blob);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class VipsValue
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_value_get_ref_string")]
|
||||||
|
internal static extern nint GetRefString(in GValue.Struct value, out ulong length);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_value_set_ref_string")]
|
||||||
|
internal static extern void SetRefString(ref GValue.Struct value, byte[] str);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_value_get_blob")]
|
||||||
|
internal static extern nint GetBlob(in GValue.Struct value, out ulong length);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_value_set_blob")]
|
||||||
|
internal static extern void SetBlob(ref GValue.Struct value, Vips.CallbackFn freeFn,
|
||||||
|
nint data, ulong length);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_value_set_blob_free")]
|
||||||
|
internal static extern void SetBlobFree(ref GValue.Struct value, nint data,
|
||||||
|
ulong length);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_value_get_array_double")]
|
||||||
|
internal static extern nint GetArrayDouble(in GValue.Struct value, out int n);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_value_set_array_double")]
|
||||||
|
internal static extern void SetArrayDouble(ref GValue.Struct value,
|
||||||
|
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]
|
||||||
|
double[] array, int n);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_value_get_array_int")]
|
||||||
|
internal static extern nint GetArrayInt(in GValue.Struct value, out int n);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_value_set_array_int")]
|
||||||
|
internal static extern void SetArrayInt(ref GValue.Struct value,
|
||||||
|
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]
|
||||||
|
int[] array, int n);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_value_get_array_image")]
|
||||||
|
internal static extern nint GetArrayImage(in GValue.Struct value, out int n);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_value_set_array_image")]
|
||||||
|
internal static extern void SetArrayImage(ref GValue.Struct value, int n);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class VipsImage
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_get_page_height")]
|
||||||
|
internal static extern int GetPageHeight(Image image);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_invalidate_all")]
|
||||||
|
internal static extern void InvalidateAll(Image image);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_set_progress")]
|
||||||
|
internal static extern void SetProgress(Image image, [MarshalAs(UnmanagedType.Bool)] bool progress);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_iskilled")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static extern bool IsKilled(Image image);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_set_kill")]
|
||||||
|
internal static extern void SetKill(Image image, [MarshalAs(UnmanagedType.Bool)] bool kill);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_new_from_memory")]
|
||||||
|
internal static extern nint NewFromMemory(nint data, nuint size, int width, int height,
|
||||||
|
int bands, BandFormat format);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_new_from_memory")]
|
||||||
|
internal static extern unsafe nint NewFromMemory(void* data, nuint size, int width, int height,
|
||||||
|
int bands, BandFormat format);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_new_from_memory_copy")]
|
||||||
|
internal static extern nint NewFromMemoryCopy(nint data, nuint size, int width, int height,
|
||||||
|
int bands, BandFormat format);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_new_from_memory_copy")]
|
||||||
|
internal static extern unsafe nint NewFromMemoryCopy(void* data, nuint size, int width, int height,
|
||||||
|
int bands, BandFormat format);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_new_matrix_from_array")]
|
||||||
|
internal static extern nint NewMatrixFromArray(int width, int height, double[] array, int size);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_new_temp_file")]
|
||||||
|
internal static extern nint NewTempFile(byte[] format);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_write")]
|
||||||
|
internal static extern int Write(Image image, Image @out);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_write_to_memory")]
|
||||||
|
internal static extern nint WriteToMemory(Image @in, out ulong size);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_hasalpha")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static extern bool HasAlpha(Image image);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_addalpha")]
|
||||||
|
internal static extern int AddAlpha(Image image, out nint @out, nint sentinel = default);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_copy_memory")]
|
||||||
|
internal static extern nint CopyMemory(Image image);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl, EntryPoint = "vips_image_set")]
|
||||||
|
internal static extern void Set(Image image, [MarshalAs(UnmanagedType.LPStr)] string name,
|
||||||
|
in GValue.Struct value);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl, EntryPoint = "vips_image_get")]
|
||||||
|
internal static extern int Get(Image image, [MarshalAs(UnmanagedType.LPStr)] string name,
|
||||||
|
out GValue.Struct valueCopy);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_get_typeof")]
|
||||||
|
internal static extern nint GetTypeof(Image image, [MarshalAs(UnmanagedType.LPStr)] string name);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_remove")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static extern bool Remove(Image image, [MarshalAs(UnmanagedType.LPStr)] string name);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_image_get_fields")]
|
||||||
|
internal static extern nint GetFields(Image image);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class VipsInterpolate
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_interpolate_new")]
|
||||||
|
internal static extern nint New([MarshalAs(UnmanagedType.LPStr)] string nickname);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class VipsRegion
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_region_new")]
|
||||||
|
internal static extern nint New(Image image);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_region_fetch")]
|
||||||
|
internal static extern nint Fetch(Region region, int left, int top, int width, int height, out ulong length);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_region_width")]
|
||||||
|
internal static extern int Width(Region region);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_region_height")]
|
||||||
|
internal static extern int Height(Region region);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class VipsOperation
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_operation_get_flags")]
|
||||||
|
internal static extern OperationFlags GetFlags(Operation operation);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_operation_new")]
|
||||||
|
internal static extern nint New([MarshalAs(UnmanagedType.LPStr)] string name);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_cache_operation_build")]
|
||||||
|
internal static extern nint Build(Operation operation);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_operation_flags_get_type")]
|
||||||
|
internal static extern nint FlagsGetType();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_operation_block_set")]
|
||||||
|
internal static extern void BlockSet([MarshalAs(UnmanagedType.LPStr)] string name,
|
||||||
|
[MarshalAs(UnmanagedType.Bool)] bool state);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class VipsForeign
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_foreign_find_load")]
|
||||||
|
internal static extern nint FindLoad(nint filename);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_foreign_find_load")]
|
||||||
|
internal static extern nint FindLoad(byte[] filename);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_foreign_find_load_buffer")]
|
||||||
|
internal static extern nint FindLoadBuffer(byte[] data, ulong size);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_foreign_find_load_buffer")]
|
||||||
|
internal static extern nint FindLoadBuffer(nint data, ulong size);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_foreign_find_load_buffer")]
|
||||||
|
internal static extern unsafe nint FindLoadBuffer(void* data, ulong size);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_foreign_find_load_source")]
|
||||||
|
internal static extern nint FindLoadSource(Source stream);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_foreign_find_save")]
|
||||||
|
internal static extern nint FindSave(nint filename);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_foreign_find_save_buffer")]
|
||||||
|
internal static extern nint FindSaveBuffer(byte[] name);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_foreign_find_save_target")]
|
||||||
|
internal static extern nint FindSaveTarget(byte[] name);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_foreign_get_suffixes")]
|
||||||
|
internal static extern nint GetSuffixes();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class VipsConnection
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_connection_filename")]
|
||||||
|
internal static extern nint FileName(Connection connection);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl, EntryPoint = "vips_connection_nick")]
|
||||||
|
internal static extern nint Nick(Connection connection);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class VipsSource
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_source_new_from_descriptor")]
|
||||||
|
internal static extern nint NewFromDescriptor(int descriptor);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_source_new_from_file")]
|
||||||
|
internal static extern nint NewFromFile(byte[] filename);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_source_new_from_blob")]
|
||||||
|
internal static extern nint NewFromBlob(VipsBlobManaged blob);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_source_new_from_memory")]
|
||||||
|
internal static extern nint NewFromMemory(nint data, nuint size);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl, EntryPoint = "vips_source_map_blob")]
|
||||||
|
internal static extern nint MapBlob(Source source);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class VipsSourceCustom
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_source_custom_new")]
|
||||||
|
internal static extern nint New();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate long ReadSignal(nint sourcePtr, nint buffer, long length, nint userDataPtr);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate long SeekSignal(nint sourcePtr, long offset, int whence, nint userDataPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class VipsTarget
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_target_new_to_descriptor")]
|
||||||
|
internal static extern nint NewToDescriptor(int descriptor);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_target_new_to_file")]
|
||||||
|
internal static extern nint NewToFile(byte[] filename);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_target_new_to_memory")]
|
||||||
|
internal static extern nint NewToMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class VipsTargetCustom
|
||||||
|
{
|
||||||
|
[SuppressUnmanagedCodeSecurity]
|
||||||
|
[DllImport(Libraries.Vips, CallingConvention = CallingConvention.Cdecl,
|
||||||
|
EntryPoint = "vips_target_custom_new")]
|
||||||
|
internal static extern nint New();
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate long WriteSignal(nint targetPtr,
|
||||||
|
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)]
|
||||||
|
byte[] buffer, int length, nint userDataPtr);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate long ReadSignal(nint targetPtr, nint buffer, long length, nint userDataPtr);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate long SeekSignal(nint targetPtr, long offset, int whence, nint userDataPtr);
|
||||||
|
|
||||||
|
[SuppressUnmanagedCodeSecurity, UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
internal delegate int EndSignal(nint targetPtr, nint userDataPtr);
|
||||||
|
}
|
||||||
12
vendor/NetVips/Interop/Libraries.cs
vendored
Normal file
12
vendor/NetVips/Interop/Libraries.cs
vendored
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace NetVips.Interop;
|
||||||
|
|
||||||
|
internal static class Libraries
|
||||||
|
{
|
||||||
|
/// <remarks>
|
||||||
|
/// These library names are remapped in a cross-platform manner,
|
||||||
|
/// <see cref="ModuleInitializer.Initialize"/>.
|
||||||
|
/// </remarks>
|
||||||
|
internal const string GLib = "libglib-2.0-0.dll",
|
||||||
|
GObject = "libgobject-2.0-0.dll",
|
||||||
|
Vips = "libvips-42.dll";
|
||||||
|
}
|
||||||
43
vendor/NetVips/Interpolate.cs
vendored
Normal file
43
vendor/NetVips/Interpolate.cs
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
||||||
|
using System;
|
||||||
|
using NetVips.Internal;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make interpolators for operators like <see cref="Image.Affine"/>.
|
||||||
|
/// </summary>
|
||||||
|
public class Interpolate : VipsObject
|
||||||
|
{
|
||||||
|
private Interpolate(nint pointer) : base(pointer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make a new interpolator by name.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Make a new interpolator from the libvips class nickname. For example:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// var inter = Interpolate.NewFromName("bicubic");
|
||||||
|
/// </code>
|
||||||
|
/// You can get a list of all supported interpolators from the command-line
|
||||||
|
/// with:
|
||||||
|
/// <code language="lang-shell">
|
||||||
|
/// $ vips -l interpolate
|
||||||
|
/// </code>
|
||||||
|
/// See for example <see cref="Image.Affine"/>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="name">libvips class nickname.</param>
|
||||||
|
/// <returns>A new <see cref="Interpolate"/>.</returns>
|
||||||
|
/// <exception cref="VipsException">If unable to make a new interpolator from <paramref name="name"/>.</exception>
|
||||||
|
public static Interpolate NewFromName(string name)
|
||||||
|
{
|
||||||
|
var vi = VipsInterpolate.New(name);
|
||||||
|
if (vi == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new VipsException($"no such interpolator {name}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Interpolate(vi);
|
||||||
|
}
|
||||||
|
}
|
||||||
219
vendor/NetVips/Introspect.cs
vendored
Normal file
219
vendor/NetVips/Introspect.cs
vendored
Normal file
|
|
@ -0,0 +1,219 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using NetVips.Internal;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Build introspection data for operations.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Make an operation, introspect it, and build a structure representing
|
||||||
|
/// everything we know about it.
|
||||||
|
/// </remarks>
|
||||||
|
public class Introspect
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A cache for introspection data.
|
||||||
|
/// </summary>
|
||||||
|
private static readonly ConcurrentDictionary<string, Introspect> IntrospectCache = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An object structure that encapsulates the metadata
|
||||||
|
/// required to specify arguments.
|
||||||
|
/// </summary>
|
||||||
|
public struct Argument
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Name of this argument.
|
||||||
|
/// </summary>
|
||||||
|
public string Name;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Flags for this argument.
|
||||||
|
/// </summary>
|
||||||
|
public Enums.ArgumentFlags Flags;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The GType for this argument.
|
||||||
|
/// </summary>
|
||||||
|
public nint Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The first required input image or <see langword="null"/>.
|
||||||
|
/// </summary>
|
||||||
|
public Argument? MemberX;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A bool indicating if this operation is mutable.
|
||||||
|
/// </summary>
|
||||||
|
public readonly bool Mutable;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The required input for this operation.
|
||||||
|
/// </summary>
|
||||||
|
public readonly List<Argument> RequiredInput = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The optional input for this operation.
|
||||||
|
/// </summary>
|
||||||
|
public readonly Dictionary<string, Argument> OptionalInput = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The required output for this operation.
|
||||||
|
/// </summary>
|
||||||
|
public readonly List<Argument> RequiredOutput = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The optional output for this operation.
|
||||||
|
/// </summary>
|
||||||
|
public readonly Dictionary<string, Argument> OptionalOutput = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Build introspection data for a specified operation name.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="operationName">The operation name to introspect.</param>
|
||||||
|
private Introspect(string operationName)
|
||||||
|
{
|
||||||
|
using var op = Operation.NewFromName(operationName);
|
||||||
|
var arguments = GetArgs(op);
|
||||||
|
|
||||||
|
foreach (var entry in arguments)
|
||||||
|
{
|
||||||
|
var name = entry.Key;
|
||||||
|
var flag = entry.Value;
|
||||||
|
var gtype = op.GetTypeOf(name);
|
||||||
|
|
||||||
|
var details = new Argument
|
||||||
|
{
|
||||||
|
Name = name,
|
||||||
|
Flags = flag,
|
||||||
|
Type = gtype
|
||||||
|
};
|
||||||
|
|
||||||
|
if ((flag & Enums.ArgumentFlags.INPUT) != 0)
|
||||||
|
{
|
||||||
|
if ((flag & Enums.ArgumentFlags.REQUIRED) != 0 &&
|
||||||
|
(flag & Enums.ArgumentFlags.DEPRECATED) == 0)
|
||||||
|
{
|
||||||
|
// the first required input image arg will be self
|
||||||
|
if (!MemberX.HasValue && gtype == GValue.ImageType)
|
||||||
|
{
|
||||||
|
MemberX = details;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RequiredInput.Add(details);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we allow deprecated optional args
|
||||||
|
OptionalInput[name] = details;
|
||||||
|
}
|
||||||
|
|
||||||
|
// modified input arguments count as mutable.
|
||||||
|
if ((flag & Enums.ArgumentFlags.MODIFY) != 0 &&
|
||||||
|
(flag & Enums.ArgumentFlags.REQUIRED) != 0 &&
|
||||||
|
(flag & Enums.ArgumentFlags.DEPRECATED) == 0)
|
||||||
|
{
|
||||||
|
Mutable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((flag & Enums.ArgumentFlags.OUTPUT) != 0)
|
||||||
|
{
|
||||||
|
if ((flag & Enums.ArgumentFlags.REQUIRED) != 0 &&
|
||||||
|
(flag & Enums.ArgumentFlags.DEPRECATED) == 0)
|
||||||
|
{
|
||||||
|
RequiredOutput.Add(details);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// again, allow deprecated optional args
|
||||||
|
OptionalOutput[name] = details;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get all arguments for an operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Not quick! Try to call this infrequently.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="operation">Operation to lookup.</param>
|
||||||
|
/// <returns>Arguments for the operation.</returns>
|
||||||
|
private IEnumerable<KeyValuePair<string, Enums.ArgumentFlags>> GetArgs(Operation operation)
|
||||||
|
{
|
||||||
|
var args = new List<KeyValuePair<string, Enums.ArgumentFlags>>();
|
||||||
|
|
||||||
|
void AddArg(string name, Enums.ArgumentFlags flags)
|
||||||
|
{
|
||||||
|
// libvips uses '-' to separate parts of arg names, but we
|
||||||
|
// need '_' for C#
|
||||||
|
name = name.Replace("-", "_");
|
||||||
|
|
||||||
|
args.Add(new KeyValuePair<string, Enums.ArgumentFlags>(name, flags));
|
||||||
|
}
|
||||||
|
|
||||||
|
// vips_object_get_args was added in 8.7
|
||||||
|
if (NetVips.AtLeastLibvips(8, 7))
|
||||||
|
{
|
||||||
|
var result = Internal.VipsObject.GetArgs(operation, out var names, out var flags, out var nArgs);
|
||||||
|
|
||||||
|
if (result != 0)
|
||||||
|
{
|
||||||
|
throw new VipsException("unable to get arguments from operation");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < nArgs; i++)
|
||||||
|
{
|
||||||
|
var flag = (Enums.ArgumentFlags)Marshal.PtrToStructure<int>(flags + i * sizeof(int));
|
||||||
|
if ((flag & Enums.ArgumentFlags.CONSTRUCT) == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var name = Marshal.PtrToStringAnsi(Marshal.ReadIntPtr(names, i * IntPtr.Size));
|
||||||
|
|
||||||
|
AddArg(name, flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nint AddConstruct(nint self, nint pspec, nint argumentClass, nint argumentInstance,
|
||||||
|
nint a, nint b)
|
||||||
|
{
|
||||||
|
var flags = Marshal.PtrToStructure<VipsArgumentClass>(argumentClass).Flags;
|
||||||
|
if ((flags & Enums.ArgumentFlags.CONSTRUCT) == 0)
|
||||||
|
{
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
var name = Marshal.PtrToStringAnsi(Marshal.PtrToStructure<GParamSpec.Struct>(pspec).Name);
|
||||||
|
|
||||||
|
AddArg(name, flags);
|
||||||
|
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vips.ArgumentMap(operation, AddConstruct, IntPtr.Zero, IntPtr.Zero);
|
||||||
|
}
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get introspection data for a specified operation name.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="operationName">Operation name.</param>
|
||||||
|
/// <returns>Introspection data.</returns>
|
||||||
|
public static Introspect Get(string operationName)
|
||||||
|
{
|
||||||
|
return IntrospectCache.GetOrAdd(operationName, name => new Introspect(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
21
vendor/NetVips/LICENSE
vendored
Normal file
21
vendor/NetVips/LICENSE
vendored
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2018-present Kleis Auke Wolthuizen
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
137
vendor/NetVips/Log.cs
vendored
Normal file
137
vendor/NetVips/Log.cs
vendored
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using NetVips.Internal;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wrapper for message logging functions.
|
||||||
|
/// </summary>
|
||||||
|
public static class Log
|
||||||
|
{
|
||||||
|
private static GLib.LogFuncNative _nativeHandler;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies the prototype of log handler functions.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logDomain">The log domain of the message.</param>
|
||||||
|
/// <param name="logLevel">The log level of the message (including the fatal and recursion flags).</param>
|
||||||
|
/// <param name="message">The message to process.</param>
|
||||||
|
public delegate void LogDelegate(string logDomain, Enums.LogLevelFlags logLevel, string message);
|
||||||
|
|
||||||
|
private static void NativeCallback(string logDomain, Enums.LogLevelFlags flags, nint messagePtr,
|
||||||
|
nint userData)
|
||||||
|
{
|
||||||
|
if (userData == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var message = messagePtr.ToUtf8String();
|
||||||
|
var gch = (GCHandle)userData;
|
||||||
|
if (gch.Target is LogDelegate func)
|
||||||
|
{
|
||||||
|
func(logDomain, flags, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly ConcurrentDictionary<uint, GCHandle> Handlers = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the log handler for a domain and a set of log levels.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logDomain">The log domain, or <see langword="null"/> for the default "" application domain.</param>
|
||||||
|
/// <param name="flags">The log levels to apply the log handler for.</param>
|
||||||
|
/// <param name="logFunc">The log handler function.</param>
|
||||||
|
/// <returns>The id of the handler.</returns>
|
||||||
|
public static uint SetLogHandler(string logDomain, Enums.LogLevelFlags flags, LogDelegate logFunc)
|
||||||
|
{
|
||||||
|
_nativeHandler ??= NativeCallback;
|
||||||
|
|
||||||
|
var gch = GCHandle.Alloc(logFunc);
|
||||||
|
var result = GLib.GLogSetHandler(logDomain, flags, _nativeHandler, (nint)gch);
|
||||||
|
Handlers.AddOrUpdate(result, gch, (_, _) => gch);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes the log handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logDomain">The log domain.</param>
|
||||||
|
/// <param name="handlerId">The id of the handler, which was returned in <see cref="SetLogHandler"/>.</param>
|
||||||
|
public static void RemoveLogHandler(string logDomain, uint handlerId)
|
||||||
|
{
|
||||||
|
if (Handlers != null &&
|
||||||
|
Handlers.ContainsKey(handlerId) &&
|
||||||
|
Handlers.TryRemove(handlerId, out var handler))
|
||||||
|
{
|
||||||
|
handler.Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
GLib.GLogRemoveHandler(logDomain, handlerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the message levels which are always fatal, in any log domain.
|
||||||
|
/// When a message with any of these levels is logged the program terminates.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fatalMask">The mask containing bits set for each level of error which is to be fatal.</param>
|
||||||
|
/// <returns>The old fatal mask.</returns>
|
||||||
|
public static Enums.LogLevelFlags SetAlwaysFatal(Enums.LogLevelFlags fatalMask)
|
||||||
|
{
|
||||||
|
return GLib.GLogSetAlwaysFatal(fatalMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the log levels which are fatal in the given domain.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logDomain">The log domain.</param>
|
||||||
|
/// <param name="fatalMask">The new fatal mask.</param>
|
||||||
|
/// <returns>The old fatal mask for the log domain.</returns>
|
||||||
|
public static Enums.LogLevelFlags SetAlwaysFatal(string logDomain, Enums.LogLevelFlags fatalMask)
|
||||||
|
{
|
||||||
|
return GLib.GLogSetFatalMask(logDomain, fatalMask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Common logging method.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Sample usage:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// // Print the messages for the NULL domain
|
||||||
|
/// var logFunc = new LogFunc(Log.PrintLogFunction);
|
||||||
|
/// Log.SetLogHandler(null, Enums.LogLevelFlags.All, logFunc);
|
||||||
|
/// </code>
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="domain">The log domain of the message.</param>
|
||||||
|
/// <param name="level">The log level of the message (including the fatal and recursion flags).</param>
|
||||||
|
/// <param name="message">The message to process.</param>
|
||||||
|
public static void PrintLogFunction(string domain, Enums.LogLevelFlags level, string message)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Domain: '{0}' Level: {1}", domain, level);
|
||||||
|
Console.WriteLine("Message: {0}", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Common logging method.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Sample usage:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// // Print messages and stack trace for vips critical messages
|
||||||
|
/// var logFunc = new LogFunc(Log.PrintTraceLogFunction);
|
||||||
|
/// Log.SetLogHandler("VIPS", Enums.LogLevelFlags.Critical, logFunc);
|
||||||
|
/// </code>
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="domain">The log domain of the message.</param>
|
||||||
|
/// <param name="level">The log level of the message (including the fatal and recursion flags).</param>
|
||||||
|
/// <param name="message">The message to process.</param>
|
||||||
|
public static void PrintTraceLogFunction(string domain, Enums.LogLevelFlags level, string message)
|
||||||
|
{
|
||||||
|
PrintLogFunction(domain, level, message);
|
||||||
|
Console.WriteLine("Trace follows:\n{0}", new StackTrace());
|
||||||
|
}
|
||||||
|
}
|
||||||
139
vendor/NetVips/ModuleInitializer.cs
vendored
Normal file
139
vendor/NetVips/ModuleInitializer.cs
vendored
Normal file
|
|
@ -0,0 +1,139 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using NetVips.Interop;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// All code inside the <see cref="Initialize"/> method is ran as soon as the assembly is loaded.
|
||||||
|
/// </summary>
|
||||||
|
public static class ModuleInitializer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Is vips initialized?
|
||||||
|
/// </summary>
|
||||||
|
public static bool VipsInitialized;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contains the exception when initialization of libvips fails.
|
||||||
|
/// </summary>
|
||||||
|
public static Exception Exception;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Could contain the version number of libvips in an 3-bytes integer.
|
||||||
|
/// </summary>
|
||||||
|
public static int? Version;
|
||||||
|
|
||||||
|
#if NET6_0_OR_GREATER
|
||||||
|
/// <summary>
|
||||||
|
/// Windows specific: is GLib statically-linked in `libvips-42.dll`?
|
||||||
|
/// </summary>
|
||||||
|
[System.Runtime.Versioning.SupportedOSPlatform("windows")]
|
||||||
|
private static bool _gLibStaticallyLinked = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A cache for <see cref="DllImportResolver"/>.
|
||||||
|
/// </summary>
|
||||||
|
internal static readonly Dictionary<string, nint> DllImportCache = new();
|
||||||
|
|
||||||
|
internal static string RemapLibraryName(string libraryName)
|
||||||
|
{
|
||||||
|
// For Windows, we try to locate the GLib symbols within
|
||||||
|
// `libvips-42.dll` first. If these symbols cannot be found there,
|
||||||
|
// we proceed to locate them within `libglib-2.0-0.dll` and
|
||||||
|
// `libgobject-2.0-0.dll`. Note that this is only possible when
|
||||||
|
// targeting .NET 6 or higher. As a result, we always ship at least
|
||||||
|
// 3 DLLs in a separate package for .NET Framework.
|
||||||
|
if (OperatingSystem.IsWindows())
|
||||||
|
{
|
||||||
|
return _gLibStaticallyLinked ? Libraries.Vips : libraryName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Switch to `OperatingSystem.IsApplePlatform()` once public.
|
||||||
|
// See: https://github.com/dotnet/runtime/issues/113262
|
||||||
|
var isApplePlatform = OperatingSystem.IsMacOS() || OperatingSystem.IsIOS() ||
|
||||||
|
OperatingSystem.IsTvOS() || OperatingSystem.IsWatchOS();
|
||||||
|
|
||||||
|
// We can safely remap the library names to `libvips.so.42` on *nix
|
||||||
|
// and `libvips.42.dylib` on macOS since DLLImport uses dlsym() there.
|
||||||
|
// This function also searches for named symbols in the dependencies
|
||||||
|
// of the shared library. Therefore, we can provide libvips as a
|
||||||
|
// single shared library with all dependencies statically linked
|
||||||
|
// without breaking compatibility with the shared builds
|
||||||
|
// (i.e. what is usually installed via package managers).
|
||||||
|
return isApplePlatform ? "libvips.42.dylib" : "libvips.so.42";
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static nint DllImportResolver(string libraryName, Assembly assembly, DllImportSearchPath? searchPath)
|
||||||
|
{
|
||||||
|
libraryName = RemapLibraryName(libraryName);
|
||||||
|
if (DllImportCache.TryGetValue(libraryName, out var cachedHandle))
|
||||||
|
{
|
||||||
|
return cachedHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
var handle = NativeLibrary.Load(libraryName, assembly, searchPath);
|
||||||
|
DllImportCache[libraryName] = handle;
|
||||||
|
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes the module.
|
||||||
|
/// </summary>
|
||||||
|
#pragma warning disable CA2255
|
||||||
|
[System.Runtime.CompilerServices.ModuleInitializer]
|
||||||
|
#pragma warning restore CA2255
|
||||||
|
public static void Initialize()
|
||||||
|
{
|
||||||
|
#if NET6_0_OR_GREATER
|
||||||
|
try
|
||||||
|
{
|
||||||
|
NativeLibrary.SetDllImportResolver(typeof(ModuleInitializer).Assembly, DllImportResolver);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Ignored; allows this function to be called multiple times.
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
VipsInitialized = NetVips.Init();
|
||||||
|
if (VipsInitialized)
|
||||||
|
{
|
||||||
|
Version = NetVips.Version(0, false);
|
||||||
|
Version = (Version << 8) + NetVips.Version(1, false);
|
||||||
|
Version = (Version << 8) + NetVips.Version(2, false);
|
||||||
|
|
||||||
|
#if NET6_0_OR_GREATER
|
||||||
|
if (!OperatingSystem.IsWindows())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_gLibStaticallyLinked = NetVips.TypeFromName("VipsImage") != IntPtr.Zero;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
_gLibStaticallyLinked = false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Exception = new VipsException("unable to initialize libvips");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
VipsInitialized = false;
|
||||||
|
Exception = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
vendor/NetVips/ModuleInitializerAttribute.cs
vendored
Normal file
11
vendor/NetVips/ModuleInitializerAttribute.cs
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
// This file enables ModuleInitializer, a C# 9 feature to work with .NET Framework.
|
||||||
|
|
||||||
|
#if NETFRAMEWORK
|
||||||
|
namespace System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
|
||||||
|
internal sealed class ModuleInitializerAttribute : Attribute
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
293
vendor/NetVips/MutableImage.Generated.cs
vendored
Normal file
293
vendor/NetVips/MutableImage.Generated.cs
vendored
Normal file
|
|
@ -0,0 +1,293 @@
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// libvips version: 8.17.0
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
public sealed partial class MutableImage
|
||||||
|
{
|
||||||
|
#region auto-generated functions
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draw a circle on an image.
|
||||||
|
/// </summary>
|
||||||
|
/// <example>
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// image.Mutate(x => x.DrawCircle(ink, cx, cy, radius, fill: bool));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
|
/// <param name="ink">Color for pixels.</param>
|
||||||
|
/// <param name="cx">Centre of draw_circle.</param>
|
||||||
|
/// <param name="cy">Centre of draw_circle.</param>
|
||||||
|
/// <param name="radius">Radius in pixels.</param>
|
||||||
|
/// <param name="fill">Draw a solid object.</param>
|
||||||
|
public void DrawCircle(double[] ink, int cx, int cy, int radius, bool? fill = null)
|
||||||
|
{
|
||||||
|
var options = new VOption();
|
||||||
|
|
||||||
|
options.AddIfPresent(nameof(fill), fill);
|
||||||
|
|
||||||
|
this.Call("draw_circle", options, ink, cx, cy, radius);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Flood-fill an area.
|
||||||
|
/// </summary>
|
||||||
|
/// <example>
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// image.Mutate(x => x.DrawFlood(ink, x, y, test: Image, equal: bool));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
|
/// <param name="ink">Color for pixels.</param>
|
||||||
|
/// <param name="x">DrawFlood start point.</param>
|
||||||
|
/// <param name="y">DrawFlood start point.</param>
|
||||||
|
/// <param name="test">Test pixels in this image.</param>
|
||||||
|
/// <param name="equal">DrawFlood while equal to edge.</param>
|
||||||
|
public void DrawFlood(double[] ink, int x, int y, Image test = null, bool? equal = null)
|
||||||
|
{
|
||||||
|
var options = new VOption();
|
||||||
|
|
||||||
|
options.AddIfPresent(nameof(test), test);
|
||||||
|
options.AddIfPresent(nameof(equal), equal);
|
||||||
|
|
||||||
|
this.Call("draw_flood", options, ink, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Flood-fill an area.
|
||||||
|
/// </summary>
|
||||||
|
/// <example>
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// image.Mutate(x => x.DrawFlood(ink, x, y, out var left, test: Image, equal: bool));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
|
/// <param name="ink">Color for pixels.</param>
|
||||||
|
/// <param name="x">DrawFlood start point.</param>
|
||||||
|
/// <param name="y">DrawFlood start point.</param>
|
||||||
|
/// <param name="left">Left edge of modified area.</param>
|
||||||
|
/// <param name="test">Test pixels in this image.</param>
|
||||||
|
/// <param name="equal">DrawFlood while equal to edge.</param>
|
||||||
|
public void DrawFlood(double[] ink, int x, int y, out int left, Image test = null, bool? equal = null)
|
||||||
|
{
|
||||||
|
var options = new VOption();
|
||||||
|
|
||||||
|
options.AddIfPresent(nameof(test), test);
|
||||||
|
options.AddIfPresent(nameof(equal), equal);
|
||||||
|
|
||||||
|
options.Add("left", true);
|
||||||
|
|
||||||
|
var results = this.Call("draw_flood", options, ink, x, y) as object[];
|
||||||
|
|
||||||
|
var opts = results?[1] as VOption;
|
||||||
|
left = opts?["left"] is int out1 ? out1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Flood-fill an area.
|
||||||
|
/// </summary>
|
||||||
|
/// <example>
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// image.Mutate(x => x.DrawFlood(ink, x, y, out var left, out var top, test: Image, equal: bool));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
|
/// <param name="ink">Color for pixels.</param>
|
||||||
|
/// <param name="x">DrawFlood start point.</param>
|
||||||
|
/// <param name="y">DrawFlood start point.</param>
|
||||||
|
/// <param name="left">Left edge of modified area.</param>
|
||||||
|
/// <param name="top">Top edge of modified area.</param>
|
||||||
|
/// <param name="test">Test pixels in this image.</param>
|
||||||
|
/// <param name="equal">DrawFlood while equal to edge.</param>
|
||||||
|
public void DrawFlood(double[] ink, int x, int y, out int left, out int top, Image test = null, bool? equal = null)
|
||||||
|
{
|
||||||
|
var options = new VOption();
|
||||||
|
|
||||||
|
options.AddIfPresent(nameof(test), test);
|
||||||
|
options.AddIfPresent(nameof(equal), equal);
|
||||||
|
|
||||||
|
options.Add("left", true);
|
||||||
|
options.Add("top", true);
|
||||||
|
|
||||||
|
var results = this.Call("draw_flood", options, ink, x, y) as object[];
|
||||||
|
|
||||||
|
var opts = results?[1] as VOption;
|
||||||
|
left = opts?["left"] is int out1 ? out1 : 0;
|
||||||
|
top = opts?["top"] is int out2 ? out2 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Flood-fill an area.
|
||||||
|
/// </summary>
|
||||||
|
/// <example>
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// image.Mutate(x => x.DrawFlood(ink, x, y, out var left, out var top, out var width, test: Image, equal: bool));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
|
/// <param name="ink">Color for pixels.</param>
|
||||||
|
/// <param name="x">DrawFlood start point.</param>
|
||||||
|
/// <param name="y">DrawFlood start point.</param>
|
||||||
|
/// <param name="left">Left edge of modified area.</param>
|
||||||
|
/// <param name="top">Top edge of modified area.</param>
|
||||||
|
/// <param name="width">Width of modified area.</param>
|
||||||
|
/// <param name="test">Test pixels in this image.</param>
|
||||||
|
/// <param name="equal">DrawFlood while equal to edge.</param>
|
||||||
|
public void DrawFlood(double[] ink, int x, int y, out int left, out int top, out int width, Image test = null, bool? equal = null)
|
||||||
|
{
|
||||||
|
var options = new VOption();
|
||||||
|
|
||||||
|
options.AddIfPresent(nameof(test), test);
|
||||||
|
options.AddIfPresent(nameof(equal), equal);
|
||||||
|
|
||||||
|
options.Add("left", true);
|
||||||
|
options.Add("top", true);
|
||||||
|
options.Add("width", true);
|
||||||
|
|
||||||
|
var results = this.Call("draw_flood", options, ink, x, y) as object[];
|
||||||
|
|
||||||
|
var opts = results?[1] as VOption;
|
||||||
|
left = opts?["left"] is int out1 ? out1 : 0;
|
||||||
|
top = opts?["top"] is int out2 ? out2 : 0;
|
||||||
|
width = opts?["width"] is int out3 ? out3 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Flood-fill an area.
|
||||||
|
/// </summary>
|
||||||
|
/// <example>
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// image.Mutate(x => x.DrawFlood(ink, x, y, out var left, out var top, out var width, out var height, test: Image, equal: bool));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
|
/// <param name="ink">Color for pixels.</param>
|
||||||
|
/// <param name="x">DrawFlood start point.</param>
|
||||||
|
/// <param name="y">DrawFlood start point.</param>
|
||||||
|
/// <param name="left">Left edge of modified area.</param>
|
||||||
|
/// <param name="top">Top edge of modified area.</param>
|
||||||
|
/// <param name="width">Width of modified area.</param>
|
||||||
|
/// <param name="height">Height of modified area.</param>
|
||||||
|
/// <param name="test">Test pixels in this image.</param>
|
||||||
|
/// <param name="equal">DrawFlood while equal to edge.</param>
|
||||||
|
public void DrawFlood(double[] ink, int x, int y, out int left, out int top, out int width, out int height, Image test = null, bool? equal = null)
|
||||||
|
{
|
||||||
|
var options = new VOption();
|
||||||
|
|
||||||
|
options.AddIfPresent(nameof(test), test);
|
||||||
|
options.AddIfPresent(nameof(equal), equal);
|
||||||
|
|
||||||
|
options.Add("left", true);
|
||||||
|
options.Add("top", true);
|
||||||
|
options.Add("width", true);
|
||||||
|
options.Add("height", true);
|
||||||
|
|
||||||
|
var results = this.Call("draw_flood", options, ink, x, y) as object[];
|
||||||
|
|
||||||
|
var opts = results?[1] as VOption;
|
||||||
|
left = opts?["left"] is int out1 ? out1 : 0;
|
||||||
|
top = opts?["top"] is int out2 ? out2 : 0;
|
||||||
|
width = opts?["width"] is int out3 ? out3 : 0;
|
||||||
|
height = opts?["height"] is int out4 ? out4 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Paint an image into another image.
|
||||||
|
/// </summary>
|
||||||
|
/// <example>
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// image.Mutate(x => x.DrawImage(sub, x, y, mode: Enums.CombineMode));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
|
/// <param name="sub">Sub-image to insert into main image.</param>
|
||||||
|
/// <param name="x">Draw image here.</param>
|
||||||
|
/// <param name="y">Draw image here.</param>
|
||||||
|
/// <param name="mode">Combining mode.</param>
|
||||||
|
public void DrawImage(Image sub, int x, int y, Enums.CombineMode? mode = null)
|
||||||
|
{
|
||||||
|
var options = new VOption();
|
||||||
|
|
||||||
|
options.AddIfPresent(nameof(mode), mode);
|
||||||
|
|
||||||
|
this.Call("draw_image", options, sub, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draw a line on an image.
|
||||||
|
/// </summary>
|
||||||
|
/// <example>
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// image.Mutate(x => x.DrawLine(ink, x1, y1, x2, y2));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
|
/// <param name="ink">Color for pixels.</param>
|
||||||
|
/// <param name="x1">Start of draw_line.</param>
|
||||||
|
/// <param name="y1">Start of draw_line.</param>
|
||||||
|
/// <param name="x2">End of draw_line.</param>
|
||||||
|
/// <param name="y2">End of draw_line.</param>
|
||||||
|
public void DrawLine(double[] ink, int x1, int y1, int x2, int y2)
|
||||||
|
{
|
||||||
|
this.Call("draw_line", ink, x1, y1, x2, y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Draw a mask on an image.
|
||||||
|
/// </summary>
|
||||||
|
/// <example>
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// image.Mutate(x => x.DrawMask(ink, mask, x, y));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
|
/// <param name="ink">Color for pixels.</param>
|
||||||
|
/// <param name="mask">Mask of pixels to draw.</param>
|
||||||
|
/// <param name="x">Draw mask here.</param>
|
||||||
|
/// <param name="y">Draw mask here.</param>
|
||||||
|
public void DrawMask(double[] ink, Image mask, int x, int y)
|
||||||
|
{
|
||||||
|
this.Call("draw_mask", ink, mask, x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Paint a rectangle on an image.
|
||||||
|
/// </summary>
|
||||||
|
/// <example>
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// image.Mutate(x => x.DrawRect(ink, left, top, width, height, fill: bool));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
|
/// <param name="ink">Color for pixels.</param>
|
||||||
|
/// <param name="left">Rect to fill.</param>
|
||||||
|
/// <param name="top">Rect to fill.</param>
|
||||||
|
/// <param name="width">Rect to fill.</param>
|
||||||
|
/// <param name="height">Rect to fill.</param>
|
||||||
|
/// <param name="fill">Draw a solid object.</param>
|
||||||
|
public void DrawRect(double[] ink, int left, int top, int width, int height, bool? fill = null)
|
||||||
|
{
|
||||||
|
var options = new VOption();
|
||||||
|
|
||||||
|
options.AddIfPresent(nameof(fill), fill);
|
||||||
|
|
||||||
|
this.Call("draw_rect", options, ink, left, top, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Blur a rectangle on an image.
|
||||||
|
/// </summary>
|
||||||
|
/// <example>
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// image.Mutate(x => x.DrawSmudge(left, top, width, height));
|
||||||
|
/// </code>
|
||||||
|
/// </example>
|
||||||
|
/// <param name="left">Rect to fill.</param>
|
||||||
|
/// <param name="top">Rect to fill.</param>
|
||||||
|
/// <param name="width">Rect to fill.</param>
|
||||||
|
/// <param name="height">Rect to fill.</param>
|
||||||
|
public void DrawSmudge(int left, int top, int width, int height)
|
||||||
|
{
|
||||||
|
this.Call("draw_smudge", left, top, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
153
vendor/NetVips/MutableImage.cs
vendored
Normal file
153
vendor/NetVips/MutableImage.cs
vendored
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
using System;
|
||||||
|
using NetVips.Internal;
|
||||||
|
|
||||||
|
using SMath = System.Math;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This class represents a libvips image which can be modified. See
|
||||||
|
/// <see cref="Image.Mutate"/>.
|
||||||
|
/// </summary>
|
||||||
|
public sealed partial class MutableImage : Image
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="Image"/> this <see cref="MutableImage"/> is modifying.
|
||||||
|
/// Only use this once you have finished all modifications.
|
||||||
|
/// </summary>
|
||||||
|
internal Image Image { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make a <see cref="MutableImage"/> from a regular copied <see cref="Image"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is for internal use only. See <see cref="Image.Mutate"/> for the
|
||||||
|
/// user-facing interface.
|
||||||
|
/// </remarks>
|
||||||
|
internal MutableImage(Image copiedImage) : base(copiedImage.ObjectRef())
|
||||||
|
{
|
||||||
|
Image = copiedImage;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region set/remove metadata
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the type and value of an item of metadata.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Sets the type and value of an item of metadata. Any old item of the
|
||||||
|
/// same name is removed. See <see cref="GValue"/> for types.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="gtype">The GType of the metadata item to create.</param>
|
||||||
|
/// <param name="name">The name of the piece of metadata to create.</param>
|
||||||
|
/// <param name="value">The value to set as a C# value. It is
|
||||||
|
/// converted to the GType, if possible.</param>
|
||||||
|
public new void Set(nint gtype, string name, object value)
|
||||||
|
{
|
||||||
|
using var gv = new GValue();
|
||||||
|
gv.SetType(gtype);
|
||||||
|
gv.Set(value);
|
||||||
|
VipsImage.Set(this, name, in gv.Struct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the value of an item of metadata.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Sets the value of an item of metadata. The metadata item must already
|
||||||
|
/// exist.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="name">The name of the piece of metadata to set the value of.</param>
|
||||||
|
/// <param name="value">The value to set as a C# value. It is
|
||||||
|
/// converted to the type of the metadata item, if possible.</param>
|
||||||
|
/// <exception cref="T:System.ArgumentException">If metadata item <paramref name="name"/> does not exist.</exception>
|
||||||
|
public void Set(string name, object value)
|
||||||
|
{
|
||||||
|
var gtype = GetTypeOf(name);
|
||||||
|
if (gtype == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
$"metadata item {name} does not exist - use the Set(nint, string, object) overload to create and set");
|
||||||
|
}
|
||||||
|
|
||||||
|
Set(gtype, name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Remove an item of metadata.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The named metadata item is removed.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="name">The name of the piece of metadata to remove.</param>
|
||||||
|
/// <returns><see langword="true"/> if the metadata is successfully removed;
|
||||||
|
/// otherwise, <see langword="false"/>.</returns>
|
||||||
|
public bool Remove(string name)
|
||||||
|
{
|
||||||
|
return VipsImage.Remove(this, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region overrides
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overload `[]`.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Use `[]` to set band elements on an image. For example:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// using var test = image.Mutate(x => x[1] = green);
|
||||||
|
/// </code>
|
||||||
|
/// Will change band 1 (the middle band).
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="i">The band element to change.</param>
|
||||||
|
public new Image this[int i]
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
// number of bands to the left and right of value
|
||||||
|
var nLeft = SMath.Min(Bands, SMath.Max(0, i));
|
||||||
|
var nRight = SMath.Min(Bands, SMath.Max(0, Bands - 1 - i));
|
||||||
|
var offset = Bands - nRight;
|
||||||
|
using var left = nLeft > 0 ? Image.ExtractBand(0, n: nLeft) : null;
|
||||||
|
using var right = nRight > 0 ? Image.ExtractBand(offset, n: nRight) : null;
|
||||||
|
if (left == null)
|
||||||
|
{
|
||||||
|
using (Image)
|
||||||
|
{
|
||||||
|
Image = value.Bandjoin(right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (right == null)
|
||||||
|
{
|
||||||
|
using (Image)
|
||||||
|
{
|
||||||
|
Image = left.Bandjoin(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
using (Image)
|
||||||
|
{
|
||||||
|
Image = left.Bandjoin(value, right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Image"/>
|
||||||
|
public override Image Mutate(Action<MutableImage> action)
|
||||||
|
{
|
||||||
|
action.Invoke(this);
|
||||||
|
return Image;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Image"/>
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return $"<NetVips.MutableImage {Width}x{Height} {Format}, {Bands} bands, {Interpretation}>";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
424
vendor/NetVips/NetVips.cs
vendored
Normal file
424
vendor/NetVips/NetVips.cs
vendored
Normal file
|
|
@ -0,0 +1,424 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using NetVips.Internal;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Basic utility stuff.
|
||||||
|
/// </summary>
|
||||||
|
public static class NetVips
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Init() starts up the world of VIPS.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This function will be automatically called by <see cref="ModuleInitializer.Initialize"/>
|
||||||
|
/// once the assembly is loaded. You should only call this method in your own program if the
|
||||||
|
/// <see cref="ModuleInitializer"/> fails to initialize libvips.
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns><see langword="true"/> if successful started; otherwise, <see langword="false"/>.</returns>
|
||||||
|
public static bool Init()
|
||||||
|
{
|
||||||
|
return Vips.Init("NetVips") == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call this to drop caches, close plugins, terminate background threads, and finalize
|
||||||
|
/// any internal library testing.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Calling this is optional. If you don't call it, your platform will clean up for you.
|
||||||
|
/// The only negative consequences are that the leak checker (<see cref="Leak"/>)
|
||||||
|
/// and the profiler (<see cref="Profile"/>) will not work.
|
||||||
|
/// </remarks>
|
||||||
|
public static void Shutdown()
|
||||||
|
{
|
||||||
|
Vips.Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enable or disable libvips leak checking.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// With this enabled, libvips will check for object and area leaks on <see cref="Shutdown"/>.
|
||||||
|
/// Enabling this option will make libvips run slightly more slowly.
|
||||||
|
/// </remarks>
|
||||||
|
public static bool Leak
|
||||||
|
{
|
||||||
|
set => Vips.LeakSet(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enable or disable libvips profile recording.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// If set, vips will record profiling information, and dump it on <see cref="Shutdown"/>.
|
||||||
|
/// These profiles can be analyzed with the `vipsprofile` program.
|
||||||
|
/// </remarks>
|
||||||
|
public static bool Profile
|
||||||
|
{
|
||||||
|
set => Vips.ProfileSet(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the number of worker threads libvips' should create to process each image.
|
||||||
|
/// </summary>
|
||||||
|
public static int Concurrency
|
||||||
|
{
|
||||||
|
get => Vips.ConcurrencyGet();
|
||||||
|
set => Vips.ConcurrencySet(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Enable or disable SIMD.
|
||||||
|
/// </summary>
|
||||||
|
public static bool Vector
|
||||||
|
{
|
||||||
|
get => Vips.VectorIsEnabled();
|
||||||
|
set => Vips.VectorSet(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the block state on all untrusted operations.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// For example:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// NetVips.BlockUntrusted = true;
|
||||||
|
/// </code>
|
||||||
|
/// Will block all untrusted operations from running. Use:
|
||||||
|
/// <code language="lang-shell">
|
||||||
|
/// $ vips -l
|
||||||
|
/// </code>
|
||||||
|
/// at the command-line to see the class hierarchy and which
|
||||||
|
/// operations are marked as untrusted. Use
|
||||||
|
/// <see cref="Operation.Block"/> to set the block state on
|
||||||
|
/// specific operations in the libvips class hierarchy.
|
||||||
|
///
|
||||||
|
/// At least libvips 8.13 is needed.
|
||||||
|
/// </remarks>
|
||||||
|
public static bool BlockUntrusted
|
||||||
|
{
|
||||||
|
set => Vips.BlockUntrustedSet(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the major, minor or patch version number of the libvips library.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="flag">Pass 0 to get the major version number, 1 to get minor, 2 to get patch.</param>
|
||||||
|
/// <param name="fromModule"><see langword="true"/> to get this value from the pre-initialized
|
||||||
|
/// <see cref="ModuleInitializer.Version"/> variable.</param>
|
||||||
|
/// <returns>The version number.</returns>
|
||||||
|
/// <exception cref="T:System.ArgumentOutOfRangeException">If <paramref name="flag"/> is not in range.</exception>
|
||||||
|
public static int Version(int flag, bool fromModule = true)
|
||||||
|
{
|
||||||
|
if (fromModule && ModuleInitializer.Version.HasValue)
|
||||||
|
{
|
||||||
|
var version = ModuleInitializer.Version.Value;
|
||||||
|
switch (flag)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return (version >> 16) & 0xFF;
|
||||||
|
case 1:
|
||||||
|
return (version >> 8) & 0xFF;
|
||||||
|
case 2:
|
||||||
|
return version & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag is < 0 or > 2)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(flag), "Flag must be in the range of 0 to 2");
|
||||||
|
}
|
||||||
|
|
||||||
|
var value = Vips.Version(flag);
|
||||||
|
if (value < 0)
|
||||||
|
{
|
||||||
|
throw new VipsException("Unable to get library version");
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is this at least libvips major.minor[.patch]?
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="x">Major component.</param>
|
||||||
|
/// <param name="y">Minor component.</param>
|
||||||
|
/// <param name="z">Patch component.</param>
|
||||||
|
/// <returns><see langword="true"/> if at least libvips major.minor[.patch]; otherwise, <see langword="false"/>.</returns>
|
||||||
|
public static bool AtLeastLibvips(int x, int y, int z = 0)
|
||||||
|
{
|
||||||
|
var major = Version(0);
|
||||||
|
var minor = Version(1);
|
||||||
|
var patch = Version(2);
|
||||||
|
|
||||||
|
return major > x ||
|
||||||
|
major == x && minor > y ||
|
||||||
|
major == x && minor == y && patch >= z;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a list of all the filename suffixes supported by libvips.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// At least libvips 8.8 is needed.
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns>An array of strings or <see langword="null"/>.</returns>
|
||||||
|
public static string[] GetSuffixes()
|
||||||
|
{
|
||||||
|
if (!AtLeastLibvips(8, 8))
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var ptrArr = VipsForeign.GetSuffixes();
|
||||||
|
|
||||||
|
var names = new List<string>();
|
||||||
|
|
||||||
|
var count = 0;
|
||||||
|
nint strPtr;
|
||||||
|
while ((strPtr = Marshal.ReadIntPtr(ptrArr, count * IntPtr.Size)) != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
var name = Marshal.PtrToStringAnsi(strPtr);
|
||||||
|
names.Add(name);
|
||||||
|
GLib.GFree(strPtr);
|
||||||
|
++count;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLib.GFree(ptrArr);
|
||||||
|
|
||||||
|
return names.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reports leaks (hopefully there are none) it also tracks and reports peak memory use.
|
||||||
|
/// </summary>
|
||||||
|
internal static void ReportLeak()
|
||||||
|
{
|
||||||
|
VipsObject.PrintAll();
|
||||||
|
|
||||||
|
Console.WriteLine("memory: {0} allocations, {1} bytes", Stats.Allocations, Stats.Mem);
|
||||||
|
Console.WriteLine("files: {0} open", Stats.Files);
|
||||||
|
|
||||||
|
Console.WriteLine("memory: high-water mark: {0}", Stats.MemHighwater.ToReadableBytes());
|
||||||
|
|
||||||
|
var errorBuffer = Marshal.PtrToStringAnsi(Vips.ErrorBuffer());
|
||||||
|
if (!string.IsNullOrEmpty(errorBuffer))
|
||||||
|
{
|
||||||
|
Console.WriteLine("error buffer: {0}", errorBuffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#region unit test functions
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// For testing only.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Path to split.</param>
|
||||||
|
/// <returns>The filename part of a vips7 path.</returns>
|
||||||
|
internal static string PathFilename7(string path)
|
||||||
|
{
|
||||||
|
return Vips.PathFilename7(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// For testing only.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="path">Path to split.</param>
|
||||||
|
/// <returns>The mode part of a vips7 path.</returns>
|
||||||
|
internal static string PathMode7(string path)
|
||||||
|
{
|
||||||
|
return Vips.PathMode7(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// For testing only.
|
||||||
|
/// </summary>
|
||||||
|
internal static void VipsInterpretationGetType()
|
||||||
|
{
|
||||||
|
Vips.InterpretationGetType();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// For testing only.
|
||||||
|
/// </summary>
|
||||||
|
internal static void VipsOperationFlagsGetType()
|
||||||
|
{
|
||||||
|
VipsOperation.FlagsGetType();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the GType for a name.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Looks up the GType for a nickname. Types below basename in the type
|
||||||
|
/// hierarchy are searched.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="basename">Name of base class.</param>
|
||||||
|
/// <param name="nickname">Search for a class with this nickname.</param>
|
||||||
|
/// <returns>The GType of the class, or <see cref="IntPtr.Zero"/> if the class is not found.</returns>
|
||||||
|
public static nint TypeFind(string basename, string nickname)
|
||||||
|
{
|
||||||
|
return Vips.TypeFind(basename, nickname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the name for a GType.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">Type to return name for.</param>
|
||||||
|
/// <returns>Type name.</returns>
|
||||||
|
public static string TypeName(nint type)
|
||||||
|
{
|
||||||
|
return Marshal.PtrToStringAnsi(GType.Name(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the nickname for a GType.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">Type to return nickname for.</param>
|
||||||
|
/// <returns>Nickname.</returns>
|
||||||
|
public static string NicknameFind(nint type)
|
||||||
|
{
|
||||||
|
return Marshal.PtrToStringAnsi(Vips.NicknameFind(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a list of operations available within the libvips library.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This can be useful for documentation generators.
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns>A list of operations.</returns>
|
||||||
|
public static List<string> GetOperations()
|
||||||
|
{
|
||||||
|
var allNickNames = new List<string>();
|
||||||
|
var handle = GCHandle.Alloc(allNickNames);
|
||||||
|
|
||||||
|
nint TypeMap(nint type, nint a, nint b)
|
||||||
|
{
|
||||||
|
var nickname = NicknameFind(type);
|
||||||
|
|
||||||
|
// exclude base classes, for e.g. 'jpegload_base'
|
||||||
|
if (TypeFind("VipsOperation", nickname) != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
var list = (List<string>)GCHandle.FromIntPtr(a).Target;
|
||||||
|
list.Add(NicknameFind(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Vips.TypeMap(type, TypeMap, a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Vips.TypeMap(TypeFromName("VipsOperation"), TypeMap, GCHandle.ToIntPtr(handle), IntPtr.Zero);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
handle.Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort
|
||||||
|
allNickNames.Sort();
|
||||||
|
|
||||||
|
// Filter duplicates
|
||||||
|
allNickNames = allNickNames.Distinct().ToList();
|
||||||
|
|
||||||
|
return allNickNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a list of enums available within the libvips library.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A list of enums.</returns>
|
||||||
|
public static List<string> GetEnums()
|
||||||
|
{
|
||||||
|
var allEnums = new List<string>();
|
||||||
|
var handle = GCHandle.Alloc(allEnums);
|
||||||
|
|
||||||
|
nint TypeMap(nint type, nint a, nint b)
|
||||||
|
{
|
||||||
|
var nickname = TypeName(type);
|
||||||
|
|
||||||
|
var list = (List<string>)GCHandle.FromIntPtr(a).Target;
|
||||||
|
list.Add(nickname);
|
||||||
|
|
||||||
|
return Vips.TypeMap(type, TypeMap, a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Vips.TypeMap(TypeFromName("GEnum"), TypeMap, GCHandle.ToIntPtr(handle), IntPtr.Zero);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
handle.Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort
|
||||||
|
allEnums.Sort();
|
||||||
|
|
||||||
|
return allEnums;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get all values for a enum (GType).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">Type to return enum values for.</param>
|
||||||
|
/// <returns>A list of values.</returns>
|
||||||
|
public static Dictionary<string, int> ValuesForEnum(nint type)
|
||||||
|
{
|
||||||
|
var typeClass = GType.ClassRef(type);
|
||||||
|
var enumClass = Marshal.PtrToStructure<GEnumClass>(typeClass);
|
||||||
|
|
||||||
|
var values = new Dictionary<string, int>((int)enumClass.NValues);
|
||||||
|
|
||||||
|
var ptr = enumClass.Values;
|
||||||
|
for (var i = 0; i < enumClass.NValues; i++)
|
||||||
|
{
|
||||||
|
var enumValue = Marshal.PtrToStructure<GEnumValue>(ptr);
|
||||||
|
values[enumValue.ValueNick] = enumValue.Value;
|
||||||
|
|
||||||
|
ptr += Marshal.SizeOf<GEnumValue>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Return the GType for a name.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Type name to lookup.</param>
|
||||||
|
/// <returns>Corresponding type ID or <see cref="IntPtr.Zero"/>.</returns>
|
||||||
|
public static nint TypeFromName(string name)
|
||||||
|
{
|
||||||
|
return GType.FromName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extract the fundamental type ID portion.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">A valid type ID.</param>
|
||||||
|
/// <returns>Fundamental type ID.</returns>
|
||||||
|
public static nint FundamentalType(nint type)
|
||||||
|
{
|
||||||
|
return GType.Fundamental(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Frees the memory pointed to by <paramref name="mem"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is needed for <see cref="Image.WriteToMemory(out ulong)"/>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="mem">The memory to free.</param>
|
||||||
|
public static void Free(nint mem)
|
||||||
|
{
|
||||||
|
GLib.GFree(mem);
|
||||||
|
}
|
||||||
|
}
|
||||||
31
vendor/NetVips/NetVips.csproj
vendored
Normal file
31
vendor/NetVips/NetVips.csproj
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<Import Project="common.props" />
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
|
||||||
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
|
<ApplicationIcon />
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<StartupObject />
|
||||||
|
<Platforms>x64;x86;ARM64;ARM32</Platforms>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
|
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||||
|
<IsTrimmable Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net6.0'))">true</IsTrimmable>
|
||||||
|
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net8.0'))">true</IsAotCompatible>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<InternalsVisibleTo Include="$(AssemblyName).Tests" />
|
||||||
|
<InternalsVisibleTo Include="$(AssemblyName).Samples" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
|
||||||
|
<!-- Constrain the version to 4.5.1, as later versions require .NET Framework 4.6.2.
|
||||||
|
https://github.com/dotnet/maintenance-packages/issues/42
|
||||||
|
-->
|
||||||
|
<PackageReference Include="System.Buffers" Version="[4.5.1]" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
270
vendor/NetVips/Operation.cs
vendored
Normal file
270
vendor/NetVips/Operation.cs
vendored
Normal file
|
|
@ -0,0 +1,270 @@
|
||||||
|
using System;
|
||||||
|
using NetVips.Internal;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wrap a <see cref="VipsOperation"/> object.
|
||||||
|
/// </summary>
|
||||||
|
public class Operation : VipsObject
|
||||||
|
{
|
||||||
|
/// <inheritdoc cref="VipsObject"/>
|
||||||
|
private Operation(nint pointer) : base(pointer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new <see cref="VipsOperation"/> with the specified nickname.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// You'll need to set any arguments and build the operation before you can use it. See
|
||||||
|
/// <see cref="O:Call"/> for a higher-level way to make new operations.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="operationName">Nickname of operation to create.</param>
|
||||||
|
/// <returns>The new operation.</returns>
|
||||||
|
/// <exception cref="VipsException">If the operation doesn't exist.</exception>
|
||||||
|
public static Operation NewFromName(string operationName)
|
||||||
|
{
|
||||||
|
var vop = VipsOperation.New(operationName);
|
||||||
|
if (vop == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new VipsException($"no such operation {operationName}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Operation(vop);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set a GObject property. The value is converted to the property type, if possible.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The name of the property to set.</param>
|
||||||
|
/// <param name="matchImage">A <see cref="Image"/> used as guide.</param>
|
||||||
|
/// <param name="value">The value.</param>
|
||||||
|
/// <param name="gtype">The GType of the property.</param>
|
||||||
|
private void Set(nint gtype, Image matchImage, string name, object value)
|
||||||
|
{
|
||||||
|
// if the object wants an image and we have a constant, Imageize it
|
||||||
|
//
|
||||||
|
// if the object wants an image array, Imageize any constants in the
|
||||||
|
// array
|
||||||
|
if (matchImage != null)
|
||||||
|
{
|
||||||
|
if (gtype == GValue.ImageType)
|
||||||
|
{
|
||||||
|
value = Image.Imageize(matchImage, value);
|
||||||
|
}
|
||||||
|
else if (gtype == GValue.ArrayImageType)
|
||||||
|
{
|
||||||
|
if (value is not Array { Rank: 1 } values)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
$"unsupported value type {value.GetType()} for VipsArrayImage");
|
||||||
|
}
|
||||||
|
|
||||||
|
var images = new Image[values.Length];
|
||||||
|
for (var i = 0; i < values.Length; i++)
|
||||||
|
{
|
||||||
|
ref var image = ref images[i];
|
||||||
|
image = Image.Imageize(matchImage, values.GetValue(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
value = images;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Set(gtype, name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Lookup the set of flags for this operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Flags for this operation.</returns>
|
||||||
|
public Enums.OperationFlags GetFlags() => VipsOperation.GetFlags(this);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call a libvips operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Use this method to call any libvips operation. For example:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// using Image blackImage = Operation.Call("black", 10, 10) as Image;
|
||||||
|
/// </code>
|
||||||
|
/// See the Introduction for notes on how this works.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="operationName">Operation name.</param>
|
||||||
|
/// <param name="args">An arbitrary number and variety of arguments.</param>
|
||||||
|
/// <returns>A new object.</returns>
|
||||||
|
public static object Call(string operationName, params object[] args) =>
|
||||||
|
Call(operationName, null, null, args);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call a libvips operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Use this method to call any libvips operation. For example:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// using Image blackImage = Operation.Call("black", 10, 10) as Image;
|
||||||
|
/// </code>
|
||||||
|
/// See the Introduction for notes on how this works.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="operationName">Operation name.</param>
|
||||||
|
/// <param name="kwargs">Optional arguments.</param>
|
||||||
|
/// <param name="args">An arbitrary number and variety of arguments.</param>
|
||||||
|
/// <returns>A new object.</returns>
|
||||||
|
public static object Call(string operationName, VOption kwargs = null, params object[] args) =>
|
||||||
|
Call(operationName, kwargs, null, args);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Call a libvips operation.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Use this method to call any libvips operation. For example:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// using Image blackImage = Operation.Call("black", 10, 10) as Image;
|
||||||
|
/// </code>
|
||||||
|
/// See the Introduction for notes on how this works.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="operationName">Operation name.</param>
|
||||||
|
/// <param name="kwargs">Optional arguments.</param>
|
||||||
|
/// <param name="matchImage">A <see cref="Image"/> used as guide.</param>
|
||||||
|
/// <param name="args">An arbitrary number and variety of arguments.</param>
|
||||||
|
/// <returns>A new object.</returns>
|
||||||
|
public static object Call(string operationName, VOption kwargs = null, Image matchImage = null,
|
||||||
|
params object[] args)
|
||||||
|
{
|
||||||
|
// pull out the special string_options kwarg
|
||||||
|
object stringOptions = null;
|
||||||
|
kwargs?.Remove("string_options", out stringOptions);
|
||||||
|
|
||||||
|
var intro = Introspect.Get(operationName);
|
||||||
|
if (intro.RequiredInput.Count != args.Length)
|
||||||
|
{
|
||||||
|
throw new ArgumentException(
|
||||||
|
$"unable to call {operationName}: {args.Length} arguments given, but {intro.RequiredInput.Count} required");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!intro.Mutable && matchImage is MutableImage)
|
||||||
|
{
|
||||||
|
throw new VipsException($"unable to call {operationName}: operation must be mutable");
|
||||||
|
}
|
||||||
|
|
||||||
|
nint vop;
|
||||||
|
using (var op = NewFromName(operationName))
|
||||||
|
{
|
||||||
|
// set any string options before any args so they can't be
|
||||||
|
// overridden
|
||||||
|
if (stringOptions != null && !op.SetString(stringOptions as string))
|
||||||
|
{
|
||||||
|
throw new VipsException($"unable to call {operationName}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// set all required inputs
|
||||||
|
if (matchImage != null && intro.MemberX.HasValue)
|
||||||
|
{
|
||||||
|
var memberX = intro.MemberX.Value;
|
||||||
|
op.Set(memberX.Type, memberX.Name, matchImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < intro.RequiredInput.Count; i++)
|
||||||
|
{
|
||||||
|
var arg = intro.RequiredInput[i];
|
||||||
|
op.Set(arg.Type, matchImage, arg.Name, args[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// set all optional inputs, if any
|
||||||
|
if (kwargs != null)
|
||||||
|
{
|
||||||
|
foreach (var item in kwargs)
|
||||||
|
{
|
||||||
|
var name = item.Key;
|
||||||
|
var value = item.Value;
|
||||||
|
|
||||||
|
if (intro.OptionalInput.TryGetValue(name, out var arg))
|
||||||
|
{
|
||||||
|
op.Set(arg.Type, matchImage, name, value);
|
||||||
|
}
|
||||||
|
else if (!intro.OptionalOutput.ContainsKey(name))
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"{operationName} does not support optional argument: {name}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// build operation
|
||||||
|
vop = VipsOperation.Build(op);
|
||||||
|
if (vop == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Internal.VipsObject.UnrefOutputs(op);
|
||||||
|
throw new VipsException($"unable to call {operationName}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var results = new object[intro.RequiredOutput.Count];
|
||||||
|
using (var op = new Operation(vop))
|
||||||
|
{
|
||||||
|
// get all required results
|
||||||
|
for (var i = 0; i < intro.RequiredOutput.Count; i++)
|
||||||
|
{
|
||||||
|
var arg = intro.RequiredOutput[i];
|
||||||
|
|
||||||
|
ref var result = ref results[i];
|
||||||
|
result = op.Get(arg.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetch optional output args, if any
|
||||||
|
if (kwargs != null)
|
||||||
|
{
|
||||||
|
var optionalArgs = new VOption();
|
||||||
|
|
||||||
|
foreach (var item in kwargs)
|
||||||
|
{
|
||||||
|
var name = item.Key;
|
||||||
|
|
||||||
|
if (intro.OptionalOutput.ContainsKey(name))
|
||||||
|
{
|
||||||
|
optionalArgs[name] = op.Get(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (optionalArgs.Count > 0)
|
||||||
|
{
|
||||||
|
var resultsLength = results.Length;
|
||||||
|
Array.Resize(ref results, resultsLength + 1);
|
||||||
|
results[resultsLength] = optionalArgs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Internal.VipsObject.UnrefOutputs(op);
|
||||||
|
}
|
||||||
|
|
||||||
|
return results.Length == 1 ? results[0] : results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set the block state on all operations in the libvips class hierarchy at
|
||||||
|
/// <paramref name="name"/> and below.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// For example:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// Operation.Block("VipsForeignLoad", true);
|
||||||
|
/// Operation.Block("VipsForeignLoadJpeg", false);
|
||||||
|
/// </code>
|
||||||
|
/// Will block all load operations, except JPEG. Use:
|
||||||
|
/// <code language="lang-shell">
|
||||||
|
/// $ vips -l
|
||||||
|
/// </code>
|
||||||
|
/// at the command-line to see the class hierarchy.
|
||||||
|
/// Use <see cref="NetVips.BlockUntrusted"/> to set the
|
||||||
|
/// block state on all untrusted operations.
|
||||||
|
///
|
||||||
|
/// This call does nothing if the named operation is not found.
|
||||||
|
/// At least libvips 8.13 is needed.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="name">Set block state at this point and below.</param>
|
||||||
|
/// <param name="state">The block state to set.</param>
|
||||||
|
public static void Block(string name, bool state)
|
||||||
|
{
|
||||||
|
VipsOperation.BlockSet(name, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
71
vendor/NetVips/Region.cs
vendored
Normal file
71
vendor/NetVips/Region.cs
vendored
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using NetVips.Internal;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wrap a <see cref="VipsRegion"/> object.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// A region is a small part of an image. You use regions to read pixels
|
||||||
|
/// out of images without storing the entire image in memory.
|
||||||
|
/// At least libvips 8.8 is needed.
|
||||||
|
/// </remarks>
|
||||||
|
public class Region : VipsObject
|
||||||
|
{
|
||||||
|
private Region(nint pointer) : base(pointer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make a region on an image.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="image"><see cref="Image"/> to create this region on.</param>
|
||||||
|
/// <returns>A new <see cref="Region"/>.</returns>
|
||||||
|
/// <exception cref="VipsException">If unable to make a new region on <paramref name="image"/>.</exception>
|
||||||
|
public static Region New(Image image)
|
||||||
|
{
|
||||||
|
var vi = VipsRegion.New(image);
|
||||||
|
if (vi == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new VipsException("unable to make region");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Region(vi);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Width of pixels held by region.
|
||||||
|
/// </summary>
|
||||||
|
public int Width => VipsRegion.Width(this);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Height of pixels held by region.
|
||||||
|
/// </summary>
|
||||||
|
public int Height => VipsRegion.Height(this);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fetch an area of pixels.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="left">Left edge of area to fetch.</param>
|
||||||
|
/// <param name="top">Top edge of area to fetch.</param>
|
||||||
|
/// <param name="width">Width of area to fetch.</param>
|
||||||
|
/// <param name="height">Height of area to fetch.</param>
|
||||||
|
/// <returns>An array of bytes filled with pixel data.</returns>
|
||||||
|
public byte[] Fetch(int left, int top, int width, int height)
|
||||||
|
{
|
||||||
|
var pointer = VipsRegion.Fetch(this, left, top, width, height, out var size);
|
||||||
|
if (pointer == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new VipsException("unable to fetch from region");
|
||||||
|
}
|
||||||
|
|
||||||
|
var managedArray = new byte[size];
|
||||||
|
Marshal.Copy(pointer, managedArray, 0, (int)size);
|
||||||
|
|
||||||
|
GLib.GFree(pointer);
|
||||||
|
|
||||||
|
return managedArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
145
vendor/NetVips/Source.cs
vendored
Normal file
145
vendor/NetVips/Source.cs
vendored
Normal file
|
|
@ -0,0 +1,145 @@
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An input connection.
|
||||||
|
/// </summary>
|
||||||
|
public partial class Source : Connection
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Secret ref for <see cref="NewFromMemory(byte[])"/>.
|
||||||
|
/// </summary>
|
||||||
|
private GCHandle _dataHandle;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Connection"/>
|
||||||
|
internal Source(nint pointer) : base(pointer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make a new source from a file descriptor (a small integer).
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Make a new source that is attached to the descriptor. For example:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// using var source = Source.NewFromDescriptor(0);
|
||||||
|
/// </code>
|
||||||
|
/// Makes a descriptor attached to stdin.
|
||||||
|
///
|
||||||
|
/// You can pass this source to (for example) <see cref="Image.NewFromSource"/>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="descriptor">Read from this file descriptor.</param>
|
||||||
|
/// <returns>A new <see cref="Source"/>.</returns>
|
||||||
|
/// <exception cref="VipsException">If unable to create a new <see cref="Source"/> from <paramref name="descriptor"/>.</exception>
|
||||||
|
public static Source NewFromDescriptor(int descriptor)
|
||||||
|
{
|
||||||
|
var pointer = Internal.VipsSource.NewFromDescriptor(descriptor);
|
||||||
|
if (pointer == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new VipsException($"can't create source from descriptor {descriptor}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Source(pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make a new source from a filename.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Make a new source that is attached to the named file. For example:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// using var source = Source.NewFromFile("myfile.jpg");
|
||||||
|
/// </code>
|
||||||
|
/// You can pass this source to (for example) <see cref="Image.NewFromSource"/>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="filename">Read from this filename.</param>
|
||||||
|
/// <returns>A new <see cref="Source"/>.</returns>
|
||||||
|
/// <exception cref="VipsException">If unable to create a new <see cref="Source"/> from <paramref name="filename"/>.</exception>
|
||||||
|
public static Source NewFromFile(string filename)
|
||||||
|
{
|
||||||
|
var bytes = Encoding.UTF8.GetBytes(filename + char.MinValue); // Ensure null-terminated string
|
||||||
|
var pointer = Internal.VipsSource.NewFromFile(bytes);
|
||||||
|
if (pointer == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new VipsException($"can't create source from filename {filename}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Source(pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make a new source from a memory object.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Make a new source that is attached to the memory object. For example:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// using var source = Source.NewFromMemory(data);
|
||||||
|
/// </code>
|
||||||
|
/// You can pass this source to (for example) <see cref="Image.NewFromSource"/>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="data">The memory object.</param>
|
||||||
|
/// <returns>A new <see cref="Source"/>.</returns>
|
||||||
|
/// <exception cref="VipsException">If unable to create a new <see cref="Source"/> from <paramref name="data"/>.</exception>
|
||||||
|
public static Source NewFromMemory(byte[] data)
|
||||||
|
{
|
||||||
|
var handle = GCHandle.Alloc(data, GCHandleType.Pinned);
|
||||||
|
var pointer = Internal.VipsSource.NewFromMemory(handle.AddrOfPinnedObject(), (nuint)data.Length);
|
||||||
|
if (pointer == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
if (handle.IsAllocated)
|
||||||
|
{
|
||||||
|
handle.Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new VipsException("can't create input source from memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Source(pointer) { _dataHandle = handle };
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make a new source from a memory object.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Make a new source that is attached to the memory object. For example:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// using var source = Source.NewFromMemory(data);
|
||||||
|
/// </code>
|
||||||
|
/// You can pass this source to (for example) <see cref="Image.NewFromSource"/>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="data">The memory object.</param>
|
||||||
|
/// <returns>A new <see cref="Source"/>.</returns>
|
||||||
|
/// <exception cref="VipsException">If unable to create a new <see cref="Source"/> from <paramref name="data"/>.</exception>
|
||||||
|
public static Source NewFromMemory(string data) => NewFromMemory(Encoding.UTF8.GetBytes(data));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make a new source from a memory object.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Make a new source that is attached to the memory object. For example:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// using var source = Source.NewFromMemory(data);
|
||||||
|
/// </code>
|
||||||
|
/// You can pass this source to (for example) <see cref="Image.NewFromSource"/>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="data">The memory object.</param>
|
||||||
|
/// <returns>A new <see cref="Source"/>.</returns>
|
||||||
|
/// <exception cref="VipsException">If unable to create a new <see cref="Source"/> from <paramref name="data"/>.</exception>
|
||||||
|
public static Source NewFromMemory(char[] data) => NewFromMemory(Encoding.UTF8.GetBytes(data));
|
||||||
|
|
||||||
|
/// <inheritdoc cref="GObject"/>
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
// release reference to our secret ref
|
||||||
|
if (_dataHandle.IsAllocated)
|
||||||
|
{
|
||||||
|
_dataHandle.Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Call our base Dispose method
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
}
|
||||||
117
vendor/NetVips/SourceCustom.cs
vendored
Normal file
117
vendor/NetVips/SourceCustom.cs
vendored
Normal file
|
|
@ -0,0 +1,117 @@
|
||||||
|
using System.Buffers;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An source you can connect delegates to implement behaviour.
|
||||||
|
/// </summary>
|
||||||
|
public class SourceCustom : Source
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A read delegate.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The interface is exactly as <see cref="Stream.Read(byte[], int, int)"/>.
|
||||||
|
/// The handler is given a number of bytes to fetch, and should return a
|
||||||
|
/// bytes-like object containing up to that number of bytes. If there is
|
||||||
|
/// no more data available, it should return <see langword="0"/>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="buffer">An array of bytes.</param>
|
||||||
|
/// <param name="length">The maximum number of bytes to be read.</param>
|
||||||
|
/// <returns>The total number of bytes read into the buffer.</returns>
|
||||||
|
public delegate int ReadDelegate(byte[] buffer, int length);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A seek delegate.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The interface is exactly as <see cref="Stream.Seek"/>. The handler is given
|
||||||
|
/// parameters for offset and whence with the same meanings. It also returns the
|
||||||
|
/// new position within the current source.
|
||||||
|
///
|
||||||
|
/// Seek handlers are optional. If you do not set one, your source will be
|
||||||
|
/// treated as unseekable and libvips will do extra caching.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="offset">A byte offset relative to the <paramref name="origin"/>
|
||||||
|
/// parameter.</param>
|
||||||
|
/// <param name="origin">A value of type <see cref="SeekOrigin"/> indicating the
|
||||||
|
/// reference point used to obtain the new position.</param>
|
||||||
|
/// <returns>The new position within the current source.</returns>
|
||||||
|
public delegate long SeekDelegate(long offset, SeekOrigin origin);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attach a read delegate.
|
||||||
|
/// </summary>
|
||||||
|
public event ReadDelegate OnRead;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attach a seek delegate.
|
||||||
|
/// </summary>
|
||||||
|
public event SeekDelegate OnSeek;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Source"/>
|
||||||
|
public SourceCustom() : base(Internal.VipsSourceCustom.New())
|
||||||
|
{
|
||||||
|
SignalConnect("read", (Internal.VipsSourceCustom.ReadSignal)ReadHandler);
|
||||||
|
SignalConnect("seek", (Internal.VipsSourceCustom.SeekSignal)SeekHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The internal read handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourcePtr">The underlying pointer to the source.</param>
|
||||||
|
/// <param name="buffer">A pointer to an array of bytes.</param>
|
||||||
|
/// <param name="length">The maximum number of bytes to be read.</param>
|
||||||
|
/// <param name="userDataPtr">User data associated with the source.</param>
|
||||||
|
/// <returns>The total number of bytes read into the buffer.</returns>
|
||||||
|
internal long ReadHandler(nint sourcePtr, nint buffer, long length, nint userDataPtr)
|
||||||
|
{
|
||||||
|
if (length <= 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tempArray = ArrayPool<byte>.Shared.Rent((int)length);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var readLength = OnRead?.Invoke(tempArray, (int)length);
|
||||||
|
if (!readLength.HasValue)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readLength.Value > 0)
|
||||||
|
{
|
||||||
|
Marshal.Copy(tempArray, 0, buffer, readLength.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return readLength.Value;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
ArrayPool<byte>.Shared.Return(tempArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The internal seek handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sourcePtr">The underlying pointer to the source.</param>
|
||||||
|
/// <param name="offset">A byte offset relative to the <paramref name="whence"/>
|
||||||
|
/// parameter.</param>
|
||||||
|
/// <param name="whence">A value of type <see cref="SeekOrigin"/> indicating the
|
||||||
|
/// reference point used to obtain the new position.</param>
|
||||||
|
/// <param name="userDataPtr">User data associated with the source.</param>
|
||||||
|
/// <returns>The new position within the current source.</returns>
|
||||||
|
internal long SeekHandler(nint sourcePtr, long offset, int whence, nint userDataPtr)
|
||||||
|
{
|
||||||
|
var newPosition = OnSeek?.Invoke(offset, (SeekOrigin)whence);
|
||||||
|
return newPosition ?? -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
88
vendor/NetVips/SourceStream.cs
vendored
Normal file
88
vendor/NetVips/SourceStream.cs
vendored
Normal file
|
|
@ -0,0 +1,88 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An source connected to a readable <see cref="Stream"/>.
|
||||||
|
/// </summary>
|
||||||
|
internal class SourceStream : SourceCustom
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Read from this stream.
|
||||||
|
/// </summary>
|
||||||
|
private readonly Stream _stream;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The start position within the stream.
|
||||||
|
/// </summary>
|
||||||
|
private readonly long _startPosition;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="SourceCustom"/>
|
||||||
|
internal SourceStream(Stream stream)
|
||||||
|
{
|
||||||
|
var seekable = stream.CanSeek;
|
||||||
|
|
||||||
|
_stream = stream;
|
||||||
|
_startPosition = seekable ? _stream.Position : 0;
|
||||||
|
|
||||||
|
OnRead += Read;
|
||||||
|
if (seekable)
|
||||||
|
{
|
||||||
|
OnSeek += Seek;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a <see cref="SourceStream"/> attached to an <see cref="Stream"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">Read from this stream.</param>
|
||||||
|
/// <returns>A new <see cref="SourceStream"/>.</returns>
|
||||||
|
/// <exception cref="T:System.ArgumentException">If <paramref name="stream"/> is not readable.</exception>
|
||||||
|
internal static SourceStream NewFromStream(Stream stream)
|
||||||
|
{
|
||||||
|
if (!stream.CanRead)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("The stream should be readable.", nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new SourceStream(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attach a read handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer">An array of bytes.</param>
|
||||||
|
/// <param name="length">The maximum number of bytes to be read.</param>
|
||||||
|
/// <returns>The total number of bytes read into the buffer.</returns>
|
||||||
|
public int Read(byte[] buffer, int length)
|
||||||
|
{
|
||||||
|
return _stream.Read(buffer, 0, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attach a seek handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="offset">A byte offset relative to the <paramref name="origin"/>
|
||||||
|
/// parameter.</param>
|
||||||
|
/// <param name="origin">A value of type <see cref="SeekOrigin"/> indicating the
|
||||||
|
/// reference point used to obtain the new position.</param>
|
||||||
|
/// <returns>The new position within the current stream.</returns>
|
||||||
|
public long Seek(long offset, SeekOrigin origin)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return origin switch
|
||||||
|
{
|
||||||
|
SeekOrigin.Begin => _stream.Seek(_startPosition + offset, SeekOrigin.Begin) - _startPosition,
|
||||||
|
SeekOrigin.Current => _stream.Seek(offset, SeekOrigin.Current) - _startPosition,
|
||||||
|
SeekOrigin.End => _stream.Seek(offset, SeekOrigin.End) - _startPosition,
|
||||||
|
_ => -1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
39
vendor/NetVips/Stats.cs
vendored
Normal file
39
vendor/NetVips/Stats.cs
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
using NetVips.Internal;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A class that provides the statistics of memory usage and opened files.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// libvips watches the total amount of live tracked memory and
|
||||||
|
/// uses this information to decide when to trim caches.
|
||||||
|
/// </remarks>
|
||||||
|
public static class Stats
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Get the number of active allocations.
|
||||||
|
/// </summary>
|
||||||
|
public static int Allocations => Vips.TrackedGetAllocs();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the number of bytes currently allocated `vips_malloc()` and friends.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// libvips uses this figure to decide when to start dropping cache.
|
||||||
|
/// </remarks>
|
||||||
|
public static int Mem => Vips.TrackedGetMem();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the largest number of bytes simultaneously allocated via vips_tracked_malloc().
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Handy for estimating max memory requirements for a program.
|
||||||
|
/// </remarks>
|
||||||
|
public static ulong MemHighwater => Vips.TrackedGetMemHighwater();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the number of open files.
|
||||||
|
/// </summary>
|
||||||
|
public static int Files => Vips.TrackedGetFiles();
|
||||||
|
}
|
||||||
99
vendor/NetVips/Target.cs
vendored
Normal file
99
vendor/NetVips/Target.cs
vendored
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An output connection.
|
||||||
|
/// </summary>
|
||||||
|
public class Target : Connection
|
||||||
|
{
|
||||||
|
/// <inheritdoc cref="Connection"/>
|
||||||
|
internal Target(nint pointer) : base(pointer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the memory object held by the target when using <see cref="NewToMemory"/>.
|
||||||
|
/// </summary>
|
||||||
|
public byte[] Blob => (byte[])Get("blob");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make a new target to write to a file descriptor (a small integer).
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Make a new target that is attached to the descriptor. For example:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// using var target = Target.NewToDescriptor(1);
|
||||||
|
/// </code>
|
||||||
|
/// Makes a descriptor attached to stdout.
|
||||||
|
///
|
||||||
|
/// You can pass this target to (for example) <see cref="Image.WriteToTarget"/>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="descriptor">Write to this file descriptor.</param>
|
||||||
|
/// <returns>A new <see cref="Target"/>.</returns>
|
||||||
|
/// <exception cref="VipsException">If unable to create a new <see cref="Target"/> from <paramref name="descriptor"/>.</exception>
|
||||||
|
public static Target NewToDescriptor(int descriptor)
|
||||||
|
{
|
||||||
|
var pointer = Internal.VipsTarget.NewToDescriptor(descriptor);
|
||||||
|
if (pointer == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new VipsException($"can't create output target to descriptor {descriptor}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Target(pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make a new target to write to a file.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Make a new target that will write to the named file. For example:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// using var target = Target.NewToFile("myfile.jpg");
|
||||||
|
/// </code>
|
||||||
|
/// You can pass this target to (for example) <see cref="Image.WriteToTarget"/>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="filename">Write to this this file.</param>
|
||||||
|
/// <returns>A new <see cref="Target"/>.</returns>
|
||||||
|
/// <exception cref="VipsException">If unable to create a new <see cref="Target"/> from <paramref name="filename"/>.</exception>
|
||||||
|
public static Target NewToFile(string filename)
|
||||||
|
{
|
||||||
|
var bytes = Encoding.UTF8.GetBytes(filename + char.MinValue); // Ensure null-terminated string
|
||||||
|
var pointer = Internal.VipsTarget.NewToFile(bytes);
|
||||||
|
if (pointer == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new VipsException($"can't create output target to filename {filename}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Target(pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Make a new target to write to an area of memory.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Make a new target that will write to memory. For example:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// using var target = Target.NewToMemory();
|
||||||
|
/// </code>
|
||||||
|
/// You can pass this target to (for example) <see cref="Image.WriteToTarget"/>.
|
||||||
|
///
|
||||||
|
/// After writing to the target, fetch the bytes from the target object with:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// var bytes = target.Blob;
|
||||||
|
/// </code>
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns>A new <see cref="Target"/>.</returns>
|
||||||
|
/// <exception cref="VipsException">If unable to create a new <see cref="Target"/>.</exception>
|
||||||
|
public static Target NewToMemory()
|
||||||
|
{
|
||||||
|
var pointer = Internal.VipsTarget.NewToMemory();
|
||||||
|
if (pointer == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new VipsException("can't create output target to memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Target(pointer);
|
||||||
|
}
|
||||||
|
}
|
||||||
180
vendor/NetVips/TargetCustom.cs
vendored
Normal file
180
vendor/NetVips/TargetCustom.cs
vendored
Normal file
|
|
@ -0,0 +1,180 @@
|
||||||
|
using System.Buffers;
|
||||||
|
using System.IO;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An target you can connect delegates to implement behaviour.
|
||||||
|
/// </summary>
|
||||||
|
public class TargetCustom : Target
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A write delegate.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The interface is the same as <see cref="Stream.Write(byte[], int, int)"/>.
|
||||||
|
/// The handler is given a bytes-like object to write. However, the handler MUST
|
||||||
|
/// return the number of bytes written.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="buffer">An array of bytes.</param>
|
||||||
|
/// <param name="length">The number of bytes to be written to the current target.</param>
|
||||||
|
/// <returns>The total number of bytes written to the target.</returns>
|
||||||
|
public delegate long WriteDelegate(byte[] buffer, int length);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A read delegate.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// libtiff needs to be able to read on targets, unfortunately.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="buffer">An array of bytes.</param>
|
||||||
|
/// <param name="length">The maximum number of bytes to be read.</param>
|
||||||
|
/// <returns>The total number of bytes read into the buffer.</returns>
|
||||||
|
public delegate int ReadDelegate(byte[] buffer, int length);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A seek delegate.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// libtiff needs to be able to seek on targets, unfortunately.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="offset">A byte offset relative to the <paramref name="origin"/>
|
||||||
|
/// parameter.</param>
|
||||||
|
/// <param name="origin">A value of type <see cref="SeekOrigin"/> indicating the
|
||||||
|
/// reference point used to obtain the new position.</param>
|
||||||
|
/// <returns>The new position within the current target.</returns>
|
||||||
|
public delegate long SeekDelegate(long offset, SeekOrigin origin);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A end delegate.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This optional handler is called at the end of write. It should do any
|
||||||
|
/// cleaning up, if necessary.
|
||||||
|
/// </remarks>
|
||||||
|
/// <returns>0 on success, -1 on error.</returns>
|
||||||
|
public delegate int EndDelegate();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attach a write delegate.
|
||||||
|
/// </summary>
|
||||||
|
public event WriteDelegate OnWrite;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attach a read delegate.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is not called prior libvips 8.13.
|
||||||
|
/// </remarks>
|
||||||
|
public event ReadDelegate OnRead;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attach a seek delegate.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is not called prior libvips 8.13.
|
||||||
|
/// </remarks>
|
||||||
|
public event SeekDelegate OnSeek;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attach a end delegate.
|
||||||
|
/// </summary>
|
||||||
|
public event EndDelegate OnEnd;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="Target"/>
|
||||||
|
public TargetCustom() : base(Internal.VipsTargetCustom.New())
|
||||||
|
{
|
||||||
|
var vips813 = NetVips.AtLeastLibvips(8, 13);
|
||||||
|
|
||||||
|
SignalConnect("write", (Internal.VipsTargetCustom.WriteSignal)WriteHandler);
|
||||||
|
if (vips813)
|
||||||
|
{
|
||||||
|
SignalConnect("read", (Internal.VipsTargetCustom.ReadSignal)ReadHandler);
|
||||||
|
SignalConnect("seek", (Internal.VipsTargetCustom.SeekSignal)SeekHandler);
|
||||||
|
}
|
||||||
|
SignalConnect(vips813 ? "end" : "finish", (Internal.VipsTargetCustom.EndSignal)EndHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The internal write handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="targetPtr">The underlying pointer to the target.</param>
|
||||||
|
/// <param name="buffer">An array of bytes.</param>
|
||||||
|
/// <param name="length">The number of bytes to be written to the current target.</param>
|
||||||
|
/// <param name="userDataPtr">User data associated with the target.</param>
|
||||||
|
/// <returns>The total number of bytes written to the target.</returns>
|
||||||
|
internal long WriteHandler(nint targetPtr, byte[] buffer, int length, nint userDataPtr)
|
||||||
|
{
|
||||||
|
var bytesWritten = OnWrite?.Invoke(buffer, length);
|
||||||
|
return bytesWritten ?? -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The internal read handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="targetPtr">The underlying pointer to the target.</param>
|
||||||
|
/// <param name="buffer">A pointer to an array of bytes.</param>
|
||||||
|
/// <param name="length">The maximum number of bytes to be read.</param>
|
||||||
|
/// <param name="userDataPtr">User data associated with the target.</param>
|
||||||
|
/// <returns>The total number of bytes read into the buffer.</returns>
|
||||||
|
internal long ReadHandler(nint targetPtr, nint buffer, long length, nint userDataPtr)
|
||||||
|
{
|
||||||
|
if (length <= 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
var tempArray = ArrayPool<byte>.Shared.Rent((int)length);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var readLength = OnRead?.Invoke(tempArray, (int)length);
|
||||||
|
if (!readLength.HasValue)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readLength.Value > 0)
|
||||||
|
{
|
||||||
|
Marshal.Copy(tempArray, 0, buffer, readLength.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
return readLength.Value;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
ArrayPool<byte>.Shared.Return(tempArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The internal seek handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="targetPtr">The underlying pointer to the target.</param>
|
||||||
|
/// <param name="offset">A byte offset relative to the <paramref name="whence"/>
|
||||||
|
/// parameter.</param>
|
||||||
|
/// <param name="whence">A value of type <see cref="SeekOrigin"/> indicating the
|
||||||
|
/// reference point used to obtain the new position.</param>
|
||||||
|
/// <param name="userDataPtr">User data associated with the target.</param>
|
||||||
|
/// <returns>The new position within the current target.</returns>
|
||||||
|
internal long SeekHandler(nint targetPtr, long offset, int whence, nint userDataPtr)
|
||||||
|
{
|
||||||
|
var newPosition = OnSeek?.Invoke(offset, (SeekOrigin)whence);
|
||||||
|
return newPosition ?? -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The internal end handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="targetPtr">The underlying pointer to the target.</param>
|
||||||
|
/// <param name="userDataPtr">User data associated with the target.</param>
|
||||||
|
/// <returns>0 on success, -1 on error.</returns>
|
||||||
|
internal int EndHandler(nint targetPtr, nint userDataPtr)
|
||||||
|
{
|
||||||
|
return OnEnd?.Invoke() ?? 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
132
vendor/NetVips/TargetStream.cs
vendored
Normal file
132
vendor/NetVips/TargetStream.cs
vendored
Normal file
|
|
@ -0,0 +1,132 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An target connected to a writable <see cref="Stream"/>.
|
||||||
|
/// </summary>
|
||||||
|
internal class TargetStream : TargetCustom
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Write to this stream.
|
||||||
|
/// </summary>
|
||||||
|
private readonly Stream _stream;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The start position within the stream.
|
||||||
|
/// </summary>
|
||||||
|
private readonly long _startPosition;
|
||||||
|
|
||||||
|
/// <inheritdoc cref="GObject"/>
|
||||||
|
internal TargetStream(Stream stream)
|
||||||
|
{
|
||||||
|
var readable = stream.CanRead;
|
||||||
|
var seekable = stream.CanSeek;
|
||||||
|
|
||||||
|
_stream = stream;
|
||||||
|
_startPosition = seekable ? _stream.Position : 0;
|
||||||
|
|
||||||
|
OnWrite += Write;
|
||||||
|
if (readable)
|
||||||
|
{
|
||||||
|
OnRead += Read;
|
||||||
|
}
|
||||||
|
if (seekable)
|
||||||
|
{
|
||||||
|
OnSeek += Seek;
|
||||||
|
}
|
||||||
|
OnEnd += End;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a <see cref="TargetStream"/> which will output to a <see cref="Stream"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="stream">Write to this stream.</param>
|
||||||
|
/// <returns>A new <see cref="TargetStream"/>.</returns>
|
||||||
|
/// <exception cref="T:System.ArgumentException">If <paramref name="stream"/> is not writable.</exception>
|
||||||
|
internal static TargetStream NewFromStream(Stream stream)
|
||||||
|
{
|
||||||
|
if (!stream.CanWrite)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("The stream should be writable.", nameof(stream));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TargetStream(stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attach a write handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer">An array of bytes.</param>
|
||||||
|
/// <param name="length">The number of bytes to be written to the current stream.</param>
|
||||||
|
/// <returns>The total number of bytes written to the stream.</returns>
|
||||||
|
private long Write(byte[] buffer, int length)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_stream.Write(buffer, 0, length);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attach a read handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="buffer">An array of bytes.</param>
|
||||||
|
/// <param name="length">The maximum number of bytes to be read.</param>
|
||||||
|
/// <returns>The total number of bytes read into the buffer.</returns>
|
||||||
|
public int Read(byte[] buffer, int length)
|
||||||
|
{
|
||||||
|
return _stream.Read(buffer, 0, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attach a seek handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="offset">A byte offset relative to the <paramref name="origin"/>
|
||||||
|
/// parameter.</param>
|
||||||
|
/// <param name="origin">A value of type <see cref="SeekOrigin"/> indicating the
|
||||||
|
/// reference point used to obtain the new position.</param>
|
||||||
|
/// <returns>The new position within the current stream.</returns>
|
||||||
|
public long Seek(long offset, SeekOrigin origin)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return origin switch
|
||||||
|
{
|
||||||
|
SeekOrigin.Begin => _stream.Seek(_startPosition + offset, SeekOrigin.Begin) - _startPosition,
|
||||||
|
SeekOrigin.Current => _stream.Seek(offset, SeekOrigin.Current) - _startPosition,
|
||||||
|
SeekOrigin.End => _stream.Seek(offset, SeekOrigin.End) - _startPosition,
|
||||||
|
_ => -1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attach a end handler.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>0 on success, -1 on error.</returns>
|
||||||
|
public int End()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_stream.Flush();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
116
vendor/NetVips/VOption.cs
vendored
Normal file
116
vendor/NetVips/VOption.cs
vendored
Normal file
|
|
@ -0,0 +1,116 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This class wraps a <see cref="Dictionary{TKey,TValue}"/>.
|
||||||
|
/// This is used to call functions with optional arguments. See <see cref="Operation.Call(string, VOption, object[])"/>.
|
||||||
|
/// </summary>
|
||||||
|
public class VOption : IEnumerable<KeyValuePair<string, object>>
|
||||||
|
{
|
||||||
|
private readonly Dictionary<string, object> _internalDictionary = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns an enumerator that iterates through the <see cref="_internalDictionary"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>A <see cref="T:System.Collections.Generic.Dictionary`2.Enumerator"/> structure for the <see cref="_internalDictionary"/>.</returns>
|
||||||
|
public IEnumerator<KeyValuePair<string, object>> GetEnumerator() => _internalDictionary.GetEnumerator();
|
||||||
|
|
||||||
|
/// <inheritdoc cref="GetEnumerator"/>
|
||||||
|
IEnumerator IEnumerable.GetEnumerator() => _internalDictionary.GetEnumerator();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the value associated with the specified key.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The key of the value to get or set.</param>
|
||||||
|
/// <returns>The value associated with the specified key.</returns>
|
||||||
|
public object this[string key]
|
||||||
|
{
|
||||||
|
get => _internalDictionary[key];
|
||||||
|
set => _internalDictionary[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a collection containing the keys in the <see cref="_internalDictionary"/>.
|
||||||
|
/// </summary>
|
||||||
|
public Dictionary<string, object>.KeyCollection Keys => _internalDictionary.Keys;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the number of key/value pairs contained in the <see cref="_internalDictionary"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The number of key/value pairs contained in the <see cref="_internalDictionary"/>.</returns>
|
||||||
|
public int Count => _internalDictionary.Count;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the specified key and value to the <see cref="_internalDictionary"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The key of the element to add.</param>
|
||||||
|
/// <param name="value">The value of the element to add. The value can be null for reference types.</param>
|
||||||
|
public void Add(string key, object value) => _internalDictionary.Add(key, value);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the specified key and value to the <see cref="_internalDictionary"/>, if value is present.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The key of the element to add.</param>
|
||||||
|
/// <param name="value">The value of the element to add.</param>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void AddIfPresent<T>(string key, T? value) where T : struct
|
||||||
|
{
|
||||||
|
if (value.HasValue)
|
||||||
|
{
|
||||||
|
_internalDictionary.Add(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the specified key and class to the <see cref="_internalDictionary"/>, if class is present.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The key of the element to add.</param>
|
||||||
|
/// <param name="cls">The value of the element to add.</param>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void AddIfPresent<T>(string key, T cls) where T : class
|
||||||
|
{
|
||||||
|
if (cls != null)
|
||||||
|
{
|
||||||
|
_internalDictionary.Add(key, cls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds the specified key and array to the <see cref="_internalDictionary"/>, if array is present.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The key of the element to add.</param>
|
||||||
|
/// <param name="array">The value of the element to add.</param>
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void AddIfPresent<T>(string key, T[] array) where T : struct
|
||||||
|
{
|
||||||
|
if (array is { Length: > 0 })
|
||||||
|
{
|
||||||
|
_internalDictionary.Add(key, array);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Determines whether the <see cref="_internalDictionary"/> contains the specified key.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The key to locate in the <see cref="_internalDictionary"/>.</param>
|
||||||
|
/// <returns><see langword="true"/> if the <see cref="_internalDictionary"/> contains an element with the specified key; otherwise, <see langword="false"/>.</returns>
|
||||||
|
public bool ContainsKey(string key) => _internalDictionary.ContainsKey(key);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes the value with the specified key from the <see cref="_internalDictionary"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The key of the element to remove.</param>
|
||||||
|
/// <returns><see langword="true"/> if the element is successfully found and removed; otherwise, <see langword="false"/>.</returns>
|
||||||
|
public bool Remove(string key) => _internalDictionary.Remove(key);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the value associated with the specified key.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The key of the value to get.</param>
|
||||||
|
/// <param name="value">When this method returns, contains the value associated with the specified key, if the key is found; otherwise, the default value for the type of the value parameter. This parameter is passed uninitialized.</param>
|
||||||
|
/// <returns><see langword="true"/> if the <see cref="_internalDictionary"/> contains an element with the specified key; otherwise, <see langword="false"/>.</returns>
|
||||||
|
public bool TryGetValue(string key, out object value) => _internalDictionary.TryGetValue(key, out value);
|
||||||
|
}
|
||||||
64
vendor/NetVips/VipsBlob.cs
vendored
Normal file
64
vendor/NetVips/VipsBlob.cs
vendored
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Manage a <see cref="Internal.VipsBlob"/>.
|
||||||
|
/// </summary>
|
||||||
|
internal class VipsBlob : SafeHandle
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="VipsBlob"/> class
|
||||||
|
/// with the specified pointer to wrap around.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pointer">The pointer to wrap around.</param>
|
||||||
|
internal VipsBlob(nint pointer) : base(IntPtr.Zero, true)
|
||||||
|
{
|
||||||
|
// record the pointer we were given to manage
|
||||||
|
SetHandle(pointer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the data from a <see cref="Internal.VipsBlob"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="length">Return number of bytes of data.</param>
|
||||||
|
/// <returns>A <see langword="nint"/> containing the data.</returns>
|
||||||
|
internal nint GetData(out nuint length)
|
||||||
|
{
|
||||||
|
return Internal.VipsBlob.Get(this, out length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Decreases the reference count of the blob.
|
||||||
|
/// When its reference count drops to 0, the blob is finalized (i.e. its memory is freed).
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><see langword="true"/> if the handle is released successfully; otherwise,
|
||||||
|
/// in the event of a catastrophic failure, <see langword="false"/>.</returns>
|
||||||
|
protected override bool ReleaseHandle()
|
||||||
|
{
|
||||||
|
if (!IsInvalid)
|
||||||
|
{
|
||||||
|
// Free the VipsArea
|
||||||
|
Internal.VipsArea.Unref(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether the handle is invalid.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns><see langword="true"/> if the handle is not valid; otherwise, <see langword="false"/>.</returns>
|
||||||
|
public override bool IsInvalid => handle == IntPtr.Zero;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the number of bytes of data.
|
||||||
|
/// </summary>
|
||||||
|
internal ulong Length => Marshal.PtrToStructure<Internal.VipsArea.Struct>(handle).Length;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the reference count of the blob. Handy for debugging.
|
||||||
|
/// </summary>
|
||||||
|
internal int RefCount => Marshal.PtrToStructure<Internal.VipsArea.Struct>(handle).Count;
|
||||||
|
}
|
||||||
44
vendor/NetVips/VipsException.cs
vendored
Normal file
44
vendor/NetVips/VipsException.cs
vendored
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
using System;
|
||||||
|
using NetVips.Internal;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Our own exception class which handles the libvips error buffer.
|
||||||
|
/// </summary>
|
||||||
|
public class VipsException : Exception
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="VipsException"/> class.
|
||||||
|
/// </summary>
|
||||||
|
public VipsException()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="VipsException"/> class with a specified error message.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The message that describes the error.</param>
|
||||||
|
public VipsException(string message)
|
||||||
|
: base($"{message}{Environment.NewLine}{VipsErrorBuffer()}")
|
||||||
|
{
|
||||||
|
Vips.ErrorClear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="VipsException"/> class with a specified error message
|
||||||
|
/// and a reference to the inner exception that is the cause of this exception.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The error message that explains the reason for the exception.</param>
|
||||||
|
/// <param name="inner">The exception that is the cause of the current exception, or a null reference if no inner exception is specified.</param>
|
||||||
|
public VipsException(string message, Exception inner)
|
||||||
|
: base($"{message}{Environment.NewLine}{VipsErrorBuffer()}", inner)
|
||||||
|
{
|
||||||
|
Vips.ErrorClear();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string VipsErrorBuffer()
|
||||||
|
{
|
||||||
|
return Vips.ErrorBuffer().ToUtf8String();
|
||||||
|
}
|
||||||
|
}
|
||||||
154
vendor/NetVips/VipsObject.cs
vendored
Normal file
154
vendor/NetVips/VipsObject.cs
vendored
Normal file
|
|
@ -0,0 +1,154 @@
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using NetVips.Internal;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Manage a <see cref="Internal.VipsObject"/>.
|
||||||
|
/// </summary>
|
||||||
|
public class VipsObject : GObject
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Attach a post-close delegate. This is called on finalization.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Useful for e.g. deleting the file associated with a temp image.
|
||||||
|
/// </remarks>
|
||||||
|
public event Action OnPostClose
|
||||||
|
{
|
||||||
|
add => SignalConnect("postclose", value);
|
||||||
|
remove => SignalHandlersDisconnectByFunc(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc cref="GObject"/>
|
||||||
|
internal VipsObject(nint pointer) : base(pointer)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Print a table of all active libvips objects. Handy for debugging.
|
||||||
|
/// </summary>
|
||||||
|
internal static void PrintAll()
|
||||||
|
{
|
||||||
|
GC.Collect();
|
||||||
|
Internal.VipsObject.PrintAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// slow! eeeeew.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Arg to fetch.</param>
|
||||||
|
/// <returns>The pspec for this arg.</returns>
|
||||||
|
private GParamSpec.Struct? GetPspec(string name)
|
||||||
|
{
|
||||||
|
var argument = Internal.VipsObject.GetArgument(this, name, out var pspec, out _, out _);
|
||||||
|
|
||||||
|
return argument != 0
|
||||||
|
? default(GParamSpec.Struct?)
|
||||||
|
: Marshal.PtrToStructure<GParamSpec.Struct>(pspec);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get a GObject property.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// The value of the property is converted to a C# value.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="name">Arg to fetch.</param>
|
||||||
|
/// <returns>The GObject property.</returns>
|
||||||
|
internal object Get(string name)
|
||||||
|
{
|
||||||
|
var pspec = GetPspec(name);
|
||||||
|
if (!pspec.HasValue)
|
||||||
|
{
|
||||||
|
throw new VipsException("Property not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
var gtype = pspec.Value.ValueType;
|
||||||
|
using var gv = new GValue();
|
||||||
|
gv.SetType(gtype);
|
||||||
|
|
||||||
|
// this will add a reference for GObject properties, that ref will be
|
||||||
|
// unreferenced when the GValue is finalized
|
||||||
|
Internal.GObject.GetProperty(this, name, ref gv.Struct);
|
||||||
|
|
||||||
|
return gv.Get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set a GObject property. The value is converted to the property type, if possible.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The name of the property to set.</param>
|
||||||
|
/// <param name="value">The value.</param>
|
||||||
|
/// <param name="gtype">The GType of the property.</param>
|
||||||
|
internal void Set(nint gtype, string name, object value)
|
||||||
|
{
|
||||||
|
using var gv = new GValue();
|
||||||
|
gv.SetType(gtype);
|
||||||
|
gv.Set(value);
|
||||||
|
|
||||||
|
Internal.GObject.SetProperty(this, name, in gv.Struct);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set a series of properties using a string.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// For example:
|
||||||
|
/// "fred=12, tile"
|
||||||
|
/// "[fred=12]"
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="stringOptions">Arguments as a string.</param>
|
||||||
|
/// <returns><see langword="true"/> on success; otherwise, <see langword="false"/>.</returns>
|
||||||
|
internal bool SetString(string stringOptions)
|
||||||
|
{
|
||||||
|
var result = Internal.VipsObject.SetFromString(this, stringOptions);
|
||||||
|
return result == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the GType of a GObject property.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">The name of the GType to get the type of.</param>
|
||||||
|
/// <returns>A new instance of <see langword="nint"/> initialized to the GType or
|
||||||
|
/// <see cref="IntPtr.Zero"/> if the property does not exist.</returns>
|
||||||
|
public nint GetTypeOf(string name)
|
||||||
|
{
|
||||||
|
var pspec = GetPspec(name);
|
||||||
|
if (!pspec.HasValue)
|
||||||
|
{
|
||||||
|
// need to clear any error, this is horrible
|
||||||
|
Vips.ErrorClear();
|
||||||
|
return IntPtr.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
return pspec.Value.ValueType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the blurb for a GObject property.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name">Arg to fetch.</param>
|
||||||
|
/// <returns>The blurb.</returns>
|
||||||
|
public string GetBlurb(string name)
|
||||||
|
{
|
||||||
|
var pspec = GetPspec(name);
|
||||||
|
if (!pspec.HasValue)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var pspecValue = pspec.Value;
|
||||||
|
return Marshal.PtrToStringAnsi(GParamSpec.GetBlurb(in pspecValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Get the description of a GObject.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The description of a GObject.</returns>
|
||||||
|
public string GetDescription()
|
||||||
|
{
|
||||||
|
return Marshal.PtrToStringAnsi(Internal.VipsObject.GetDescription(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
74
vendor/NetVips/VipsProgress.cs
vendored
Normal file
74
vendor/NetVips/VipsProgress.cs
vendored
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Records a start time, and counts microseconds elapsed since that time.
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct GTimer
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Monotonic start time, in microseconds.
|
||||||
|
/// </summary>
|
||||||
|
public ulong Start;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Monotonic end time, in microseconds.
|
||||||
|
/// </summary>
|
||||||
|
public ulong End;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Is the timer currently active?
|
||||||
|
/// </summary>
|
||||||
|
[MarshalAs(UnmanagedType.I1)]
|
||||||
|
public bool Active;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Struct we keep a record of execution time in. Passed to eval signal so
|
||||||
|
/// it can assess progress.
|
||||||
|
/// </summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct VipsProgress
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Image we are part of.
|
||||||
|
/// </summary>
|
||||||
|
private nint Im;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Time we have been running.
|
||||||
|
/// </summary>
|
||||||
|
public int Run;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Estimated seconds of computation left.
|
||||||
|
/// </summary>
|
||||||
|
public int Eta;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of pels we expect to calculate.
|
||||||
|
/// </summary>
|
||||||
|
public long TPels;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Number of pels calculated so far.
|
||||||
|
/// </summary>
|
||||||
|
public long NPels;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Percent complete.
|
||||||
|
/// </summary>
|
||||||
|
public int Percent;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Start time.
|
||||||
|
/// </summary>
|
||||||
|
private nint StartPtr;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Start time.
|
||||||
|
/// </summary>
|
||||||
|
public GTimer Start => Marshal.PtrToStructure<GTimer>(StartPtr);
|
||||||
|
}
|
||||||
37
vendor/NetVips/common.props
vendored
Normal file
37
vendor/NetVips/common.props
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
<Project>
|
||||||
|
<PropertyGroup>
|
||||||
|
<Product>NetVips</Product>
|
||||||
|
<Description>.NET binding for libvips</Description>
|
||||||
|
<Copyright>Kleis Auke Wolthuizen</Copyright>
|
||||||
|
<NeutralLanguage>en-US</NeutralLanguage>
|
||||||
|
<Authors>Kleis Auke Wolthuizen</Authors>
|
||||||
|
<PackageTags>libvips;bindings;image-processing</PackageTags>
|
||||||
|
<PackageProjectUrl>https://kleisauke.github.io/net-vips</PackageProjectUrl>
|
||||||
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
|
<RepositoryType>git</RepositoryType>
|
||||||
|
<RepositoryUrl>https://github.com/kleisauke/net-vips</RepositoryUrl>
|
||||||
|
|
||||||
|
<CLSCompliant>false</CLSCompliant>
|
||||||
|
<ComVisible>false</ComVisible>
|
||||||
|
|
||||||
|
<LangVersion>11</LangVersion>
|
||||||
|
|
||||||
|
<Major>3</Major>
|
||||||
|
<Minor>1</Minor>
|
||||||
|
<Revision>0</Revision>
|
||||||
|
|
||||||
|
<BuildNumber Condition="'$(APPVEYOR_BUILD_NUMBER)' != ''">$(APPVEYOR_BUILD_NUMBER)</BuildNumber>
|
||||||
|
<BuildNumber Condition="'$(BuildNumber)' == ''">0</BuildNumber>
|
||||||
|
|
||||||
|
<PrereleaseLabel Condition="'$(APPVEYOR_BUILD_NUMBER)' != ''">-develop</PrereleaseLabel>
|
||||||
|
|
||||||
|
<PrereleaseLabelConstants></PrereleaseLabelConstants>
|
||||||
|
<PrereleaseLabelConstants Condition="'$(APPVEYOR_BUILD_NUMBER)' != ''">PRERELEASE_NIGHTLY</PrereleaseLabelConstants>
|
||||||
|
<DefineConstants>$(DefineConstants);$(PrereleaseLabelConstants)</DefineConstants>
|
||||||
|
|
||||||
|
<AssemblyVersion>$(Major).$(Minor).$(Revision).$(BuildNumber)</AssemblyVersion>
|
||||||
|
<AssemblyFileVersion>$(Major).$(Minor).$(Revision).$(BuildNumber)</AssemblyFileVersion>
|
||||||
|
<InformationalVersion>$(Major).$(Minor).$(Revision).$(BuildNumber)$(PrereleaseLabel)</InformationalVersion>
|
||||||
|
<PackageVersion>$(Major).$(Minor).$(Revision).$(BuildNumber)$(PrereleaseLabel)</PackageVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
</Project>
|
||||||
171
vendor/NetVips/net6.0/Image.cs
vendored
Normal file
171
vendor/NetVips/net6.0/Image.cs
vendored
Normal file
|
|
@ -0,0 +1,171 @@
|
||||||
|
#if NET6_0_OR_GREATER
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using NetVips.Internal;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wrap a <see cref="VipsImage"/> object.
|
||||||
|
/// </summary>
|
||||||
|
public partial class Image
|
||||||
|
{
|
||||||
|
#region helpers
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Find the name of the load operation vips will use to load a buffer.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// For example "VipsForeignLoadJpegBuffer". You can use this to work out what
|
||||||
|
/// options to pass to <see cref="NewFromBuffer(ReadOnlySpan{byte}, string, Enums.Access?, Enums.FailOn?, VOption)"/>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="data">The buffer to test.</param>
|
||||||
|
/// <param name="size">Length of the buffer.</param>
|
||||||
|
/// <returns>The name of the load operation, or <see langword="null"/>.</returns>
|
||||||
|
private static unsafe string FindLoadBuffer(void* data, ulong size) =>
|
||||||
|
Marshal.PtrToStringAnsi(VipsForeign.FindLoadBuffer(data, size));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Find the name of the load operation vips will use to load a buffer.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// For example "VipsForeignLoadJpegBuffer". You can use this to work out what
|
||||||
|
/// options to pass to <see cref="NewFromBuffer(ReadOnlySpan{byte}, string, Enums.Access?, Enums.FailOn?, VOption)"/>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="data">The buffer to test.</param>
|
||||||
|
/// <returns>The name of the load operation, or <see langword="null"/>.</returns>
|
||||||
|
public static unsafe string FindLoadBuffer(ReadOnlySpan<byte> data)
|
||||||
|
{
|
||||||
|
fixed (byte* dataFixed = data)
|
||||||
|
{
|
||||||
|
return FindLoadBuffer(dataFixed, (ulong)data.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region constructors
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Load a formatted image from memory.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This behaves exactly as <see cref="NewFromFile"/>, but the image is
|
||||||
|
/// loaded from the memory object rather than from a file. The memory
|
||||||
|
/// object can be a string or buffer.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="data">The memory object to load the image from.</param>
|
||||||
|
/// <param name="strOptions">Load options as a string. Use <see cref="string.Empty"/> for no options.</param>
|
||||||
|
/// <param name="access">Hint the expected access pattern for the image.</param>
|
||||||
|
/// <param name="failOn">The type of error that will cause load to fail. By
|
||||||
|
/// default, loaders are permissive, that is, <see cref="Enums.FailOn.None"/>.</param>
|
||||||
|
/// <param name="kwargs">Optional options that depend on the load operation.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
/// <exception cref="VipsException">If unable to load from <paramref name="data"/>.</exception>
|
||||||
|
public static unsafe Image NewFromBuffer(
|
||||||
|
ReadOnlySpan<byte> data,
|
||||||
|
string strOptions = "",
|
||||||
|
Enums.Access? access = null,
|
||||||
|
Enums.FailOn? failOn = null,
|
||||||
|
VOption kwargs = null)
|
||||||
|
{
|
||||||
|
fixed (byte* dataFixed = data)
|
||||||
|
{
|
||||||
|
var operationName = FindLoadBuffer(dataFixed, (ulong)data.Length);
|
||||||
|
if (operationName == null)
|
||||||
|
{
|
||||||
|
throw new VipsException("unable to load from buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
var options = new VOption();
|
||||||
|
if (kwargs != null)
|
||||||
|
{
|
||||||
|
options.Merge(kwargs);
|
||||||
|
}
|
||||||
|
|
||||||
|
options.AddIfPresent(nameof(access), access);
|
||||||
|
options.AddFailOn(failOn);
|
||||||
|
|
||||||
|
options.Add("string_options", strOptions);
|
||||||
|
|
||||||
|
var ptr = Internal.VipsBlob.Copy(dataFixed, (nuint)data.Length);
|
||||||
|
if (ptr == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new VipsException("unable to load from buffer");
|
||||||
|
}
|
||||||
|
|
||||||
|
using var blob = new VipsBlob(ptr);
|
||||||
|
return Operation.Call(operationName, options, blob) as Image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Wrap an image around a memory array.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">A <see cref="ReadOnlyMemory{T}"/>.</param>
|
||||||
|
/// <param name="width">Image width in pixels.</param>
|
||||||
|
/// <param name="height">Image height in pixels.</param>
|
||||||
|
/// <param name="bands">Number of bands.</param>
|
||||||
|
/// <param name="format">Band format.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
/// <exception cref="VipsException">If unable to make image from <paramref name="data"/>.</exception>
|
||||||
|
public static unsafe Image NewFromMemory<T>(
|
||||||
|
ReadOnlyMemory<T> data,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int bands,
|
||||||
|
Enums.BandFormat format) where T : unmanaged
|
||||||
|
{
|
||||||
|
var handle = data.Pin();
|
||||||
|
var vi = VipsImage.NewFromMemory(handle.Pointer, (nuint)data.Length, width, height, bands,
|
||||||
|
format);
|
||||||
|
if (vi == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
handle.Dispose();
|
||||||
|
|
||||||
|
throw new VipsException("unable to make image from memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
var image = new Image(vi) { MemoryPressure = data.Length };
|
||||||
|
|
||||||
|
// Need to release the pinned MemoryHandle when the image is closed.
|
||||||
|
image.OnPostClose += () => handle.Dispose();
|
||||||
|
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Like <see cref="NewFromMemory{T}(ReadOnlyMemory{T}, int, int, int, Enums.BandFormat)"/>, but
|
||||||
|
/// for <see cref="ReadOnlySpan{T}"/>, so we must copy as it could be allocated on the stack.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="data">A <see cref="ReadOnlySpan{T}"/>.</param>
|
||||||
|
/// <param name="width">Image width in pixels.</param>
|
||||||
|
/// <param name="height">Image height in pixels.</param>
|
||||||
|
/// <param name="bands">Number of bands.</param>
|
||||||
|
/// <param name="format">Band format.</param>
|
||||||
|
/// <returns>A new <see cref="Image"/>.</returns>
|
||||||
|
/// <exception cref="VipsException">If unable to make image from <paramref name="data"/>.</exception>
|
||||||
|
public static unsafe Image NewFromMemoryCopy<T>(
|
||||||
|
ReadOnlySpan<T> data,
|
||||||
|
int width,
|
||||||
|
int height,
|
||||||
|
int bands,
|
||||||
|
Enums.BandFormat format) where T : unmanaged
|
||||||
|
{
|
||||||
|
fixed (T* dataFixed = data)
|
||||||
|
{
|
||||||
|
var vi = VipsImage.NewFromMemoryCopy(dataFixed, (nuint)data.Length, width, height, bands, format);
|
||||||
|
if (vi == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new VipsException("unable to make image from memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Image(vi) { MemoryPressure = data.Length };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
47
vendor/NetVips/net6.0/Source.cs
vendored
Normal file
47
vendor/NetVips/net6.0/Source.cs
vendored
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
#if NET6_0_OR_GREATER
|
||||||
|
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace NetVips;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// An input connection.
|
||||||
|
/// </summary>
|
||||||
|
public partial class Source
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Make a new source from a memory object.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Make a new source that is attached to the memory object. For example:
|
||||||
|
/// <code language="lang-csharp">
|
||||||
|
/// using var source = Source.NewFromMemory(data);
|
||||||
|
/// </code>
|
||||||
|
/// You can pass this source to (for example) <see cref="Image.NewFromSource"/>.
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="data">The memory object.</param>
|
||||||
|
/// <returns>A new <see cref="Source"/>.</returns>
|
||||||
|
/// <exception cref="VipsException">If unable to create a new <see cref="Source"/> from <paramref name="data"/>.</exception>
|
||||||
|
public static unsafe Source NewFromMemory(ReadOnlySpan<byte> data)
|
||||||
|
{
|
||||||
|
fixed (byte* dataFixed = data)
|
||||||
|
{
|
||||||
|
var ptr = Internal.VipsBlob.Copy(dataFixed, (nuint)data.Length);
|
||||||
|
if (ptr == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new VipsException("can't create input source from memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
using var blob = new VipsBlob(ptr);
|
||||||
|
var pointer = Internal.VipsSource.NewFromBlob(blob);
|
||||||
|
if (pointer == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
throw new VipsException("can't create input source from memory");
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Source(pointer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
Loading…
Add table
Add a link
Reference in a new issue