/// <summary> /// Logs an error or debugging message. /// </summary> /// <param name="logDomain">the log domain, or <see langword="null" /> for the default "" application domain</param> /// <param name="flags">the log level</param> /// <param name="format">the message format</param> /// <param name="args">the parameters to insert into the format string</param> public static void WriteLog(string logDomain, Enums.LogLevelFlags flags, string format, params object[] args) { var nmessage = string.Format(format, args).ToUtf8Ptr(); GLib.GLogv(logDomain, flags, nmessage); GLib.GFree(nmessage); }
/// <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; IntPtr 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()); }
private void Invoke(string message) { var nmessage = message.ToUtf8Ptr(); native(nmessage); GLib.GFree(nmessage); }
/// <summary> /// The default log handler set up by GLib; <see cref="SetDefaultHandler"/> /// allows to install an alternate default log handler. /// </summary> /// <param name="logDomain">the log domain, or <see langword="null" /> for the default "" application domain</param> /// <param name="logLevel">the level of the message</param> /// <param name="message">the message</param> public static void DefaultHandler(string logDomain, Enums.LogLevelFlags logLevel, string message) { var nmess = message.ToUtf8Ptr(); GLib.GLogDefaultHandler(logDomain, logLevel, nmess, IntPtr.Zero); GLib.GFree(nmess); }
/// <summary> /// Marshals a C string pointer to a byte array. /// </summary> /// <remarks> /// Since encoding is not specified, the string is returned as a byte array. /// The byte array does not include the null terminator. /// </remarks> /// <param name="ptr">Pointer to the unmanaged string.</param> /// <param name="freePtr">If set to <see langword="true"/> free the unmanaged memory.</param> /// <param name="size">Size of the C string, use 0 to read until the null character.</param> /// <returns>The string as a byte array.</returns> internal static byte[] ToByteString(this IntPtr ptr, bool freePtr = false, int size = 0) { if (ptr == IntPtr.Zero) { return(null); } byte[] managedArray; if (size > 0) { managedArray = new byte[size]; Marshal.Copy(ptr, managedArray, 0, size); } else { var bytes = new List <byte>(); var offset = 0; byte b; while ((b = Marshal.ReadByte(ptr, offset++)) != 0) { bytes.Add(b); } managedArray = bytes.ToArray(); } if (freePtr) { GLib.GFree(ptr); } return(managedArray); }
private void Invoke(string logDomain, Enums.LogLevelFlags flags, string message) { var ndom = logDomain.ToUtf8Ptr(); var nmess = message.ToUtf8Ptr(); native(ndom, flags, nmess, IntPtr.Zero); GLib.GFree(ndom); GLib.GFree(nmess); }
/// <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); }
/// <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 IntPtr 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> /// Marshals a C string pointer to a byte array. /// </summary> /// <remarks> /// Since encoding is not specified, the string is returned as a byte array. /// The byte array does not include the null terminator. /// </remarks> /// <param name="ptr">Pointer to the unmanaged string.</param> /// <param name="freePtr">If set to <see langword="true" /> free the unmanaged memory.</param> /// <returns>The string as a byte array.</returns> public static byte[] ToByteString(this IntPtr ptr, bool freePtr = false) { if (ptr == IntPtr.Zero) { return(null); } var bytes = new List <byte>(); var offset = 0; byte b; while ((b = Marshal.ReadByte(ptr, offset++)) != 0) { bytes.Add(b); } if (freePtr) { GLib.GFree(ptr); } return(bytes.ToArray()); }
/// <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(IntPtr mem) { GLib.GFree(mem); }
/// <summary> /// Set a GValue. /// </summary> /// <remarks> /// The value is converted to the type of the GValue, if possible, and /// assigned. /// </remarks> /// <param name="value"></param> public void Set(object value) { // logger.Debug($"Set: value = {value}"); var gtype = GetTypeOf(); var fundamental = GType.GTypeFundamental(gtype); if (gtype == GBoolType) { Internal.GValue.GValueSetBoolean(ref Struct, Convert.ToBoolean(value) ? 1 : 0); } else if (gtype == GIntType) { Internal.GValue.GValueSetInt(ref Struct, Convert.ToInt32(value)); } else if (gtype == GDoubleType) { Internal.GValue.GValueSetDouble(ref Struct, Convert.ToDouble(value)); } else if (fundamental == GEnumType) { Internal.GValue.GValueSetEnum(ref Struct, ToEnum(gtype, value)); } else if (fundamental == GFlagsType) { Internal.GValue.GValueSetFlags(ref Struct, Convert.ToUInt32(value)); } else if (gtype == GStrType) { var pointer = Convert.ToString(value).ToUtf8Ptr(); Internal.GValue.GValueSetString(ref Struct, pointer); GLib.GFree(pointer); } else if (gtype == RefStrType) { var pointer = Convert.ToString(value).ToUtf8Ptr(); VipsType.VipsValueSetRefString(ref Struct, pointer); GLib.GFree(pointer); } else if (fundamental == GObjectType) { if (!(value is GObject gObject)) { throw new Exception( $"unsupported value type {value.GetType()} for gtype {Base.TypeName(gtype)}" ); } Internal.GObject.GValueSetObject(ref Struct, gObject); } else if (gtype == ArrayIntType) { if (!(value is IEnumerable)) { value = new[] { value }; } switch (value) { case int[] ints: VipsType.VipsValueSetArrayInt(ref Struct, ints, ints.Length); break; case double[] doubles: VipsType.VipsValueSetArrayInt(ref Struct, Array.ConvertAll(doubles, Convert.ToInt32), doubles.Length); break; case object[] objects: VipsType.VipsValueSetArrayInt(ref Struct, Array.ConvertAll(objects, Convert.ToInt32), objects.Length); break; default: throw new Exception( $"unsupported value type {value.GetType()} for gtype {Base.TypeName(gtype)}" ); } } else if (gtype == ArrayDoubleType) { if (!(value is IEnumerable)) { value = new[] { value }; } switch (value) { case double[] doubles: VipsType.VipsValueSetArrayDouble(ref Struct, doubles, doubles.Length); break; case int[] ints: VipsType.VipsValueSetArrayDouble(ref Struct, Array.ConvertAll(ints, Convert.ToDouble), ints.Length); break; case object[] objects: VipsType.VipsValueSetArrayDouble(ref Struct, Array.ConvertAll(objects, Convert.ToDouble), objects.Length); break; default: throw new Exception( $"unsupported value type {value.GetType()} for gtype {Base.TypeName(gtype)}" ); } } else if (gtype == ArrayImageType) { if (!(value is Image[] images)) { throw new Exception( $"unsupported value type {value.GetType()} for gtype {Base.TypeName(gtype)}" ); } var size = images.Length; VipsImage.VipsValueSetArrayImage(ref Struct, size); var ptrArr = VipsImage.VipsValueGetArrayImage(ref Struct, IntPtr.Zero); for (var i = 0; i < size; i++) { Marshal.WriteIntPtr(ptrArr, i * IntPtr.Size, images[i].DangerousGetHandle()); // the gvalue needs a ref on each of the images images[i].ObjectRef(); } } else if (gtype == BlobType) { int length; IntPtr memory; switch (value) { case string strValue: length = Encoding.UTF8.GetByteCount(strValue); // We need to set the blob to a copy of the string that vips // can own memory = strValue.ToUtf8Ptr(); break; case byte[] byteArrValue: length = byteArrValue.Length; memory = byteArrValue.ToPtr(); break; case char[] charArrValue: length = Encoding.UTF8.GetByteCount(charArrValue); memory = Encoding.UTF8.GetBytes(charArrValue).ToPtr(); break; default: throw new Exception( $"unsupported value type {value.GetType()} for gtype {Base.TypeName(gtype)}" ); } if (Base.AtLeastLibvips(8, 6)) { VipsType.VipsValueSetBlobFree(ref Struct, memory, (ulong)length); } else { int FreeFn(IntPtr a, IntPtr b) { GLib.GFree(a); return(0); } VipsType.VipsValueSetBlob(ref Struct, FreeFn, memory, (ulong)length); } } else { throw new Exception( $"unsupported gtype for set {Base.TypeName(gtype)}, fundamental {Base.TypeName(fundamental)}, value type {value.GetType()}" ); } }