static GValue() { Vips.VipsBandFormatGetType(); BandFormatType = Base.TypeFromName("VipsBandFormat"); if (Base.AtLeastLibvips(8, 6)) { Vips.VipsBlendModeGetType(); BlendModeType = Base.TypeFromName("VipsBlendMode"); } }
/// <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()}" ); } }