예제 #1
0
        /// <summary>
        /// Get the contents of a GValue.
        /// </summary>
        /// <remarks>
        /// The contents of the GValue are read out as a C# type.
        /// </remarks>
        /// <returns></returns>
        public object Get()
        {
            // logger.Debug($"Get: this = {this}");
            var gtype       = GetTypeOf();
            var fundamental = GType.GTypeFundamental(gtype);

            object result;

            if (gtype == GBoolType)
            {
                result = Internal.GValue.GValueGetBoolean(ref Struct) != 0;
            }
            else if (gtype == GIntType)
            {
                result = Internal.GValue.GValueGetInt(ref Struct);
            }
            else if (gtype == GDoubleType)
            {
                result = Internal.GValue.GValueGetDouble(ref Struct);
            }
            else if (fundamental == GEnumType)
            {
                result = FromEnum(gtype, Internal.GValue.GValueGetEnum(ref Struct));
            }
            else if (fundamental == GFlagsType)
            {
                result = Internal.GValue.GValueGetFlags(ref Struct);
            }
            else if (gtype == GStrType)
            {
                result = Internal.GValue.GValueGetString(ref Struct).ToUtf8String();
            }
            else if (gtype == RefStrType)
            {
                // don't bother getting the size -- assume these are always
                // null-terminated C strings
                ulong psize = 0;
                result = VipsType.VipsValueGetRefString(ref Struct, ref psize).ToUtf8String();
            }
            else if (gtype == ImageType)
            {
                // GValueGetObject() will not add a ref ... that is
                // held by the gvalue
                var vi = Internal.GObject.GValueGetObject(ref 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 psize  = 0;
                var intPtr = VipsType.VipsValueGetArrayInt(ref Struct, ref psize);

                var intArr = new int[psize];
                Marshal.Copy(intPtr, intArr, 0, psize);
                result = intArr;
            }
            else if (gtype == ArrayDoubleType)
            {
                var psize  = 0;
                var intPtr = VipsType.VipsValueGetArrayDouble(ref Struct, ref psize);

                var doubleArr = new double[psize];
                Marshal.Copy(intPtr, doubleArr, 0, psize);
                result = doubleArr;
            }
            else if (gtype == ArrayImageType)
            {
                var psize  = 0;
                var ptrArr = VipsImage.VipsValueGetArrayImage(ref Struct, ref psize);

                var images = new Image[psize];
                for (var i = 0; i < psize; i++)
                {
                    var vi = Marshal.ReadIntPtr(ptrArr, i * IntPtr.Size);
                    images[i] = new Image(vi);
                    images[i].ObjectRef();
                }

                result = images;
            }
            else if (gtype == BlobType)
            {
                ulong psize = 0;
                var   array = VipsType.VipsValueGetBlob(ref Struct, ref psize);

                // Blob types are returned as an array of bytes.
                var byteArr = new byte[psize];
                Marshal.Copy(array, byteArr, 0, (int)psize);
                result = byteArr;
            }
            else
            {
                throw new Exception($"unsupported gtype for get {Base.TypeName(gtype)}");
            }

            return(result);
        }
예제 #2
0
        /// <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()}"
                          );
            }
        }