Example #1
0
 /// <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;
     }
 }
Example #2
0
        /// <summary>
        /// Call a libvips operation.
        /// </summary>
        /// <remarks>
        /// Use this method to call any libvips operation. For example:
        /// <code language="lang-csharp">
        /// var blackImage = Operation.call("black", 10, 10);
        /// </code>
        /// See the Introduction for notes on how this works.
        /// </remarks>
        /// <param name="operationName"></param>
        /// <param name="kwargs"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        public static object Call(string operationName, VOption kwargs, params object[] args)
        {
            // logger.Debug($"VipsOperation.call: operationName = {operationName}");
            // logger.Debug($"VipsOperation.call: args = {args}, kwargs = {kwargs}");

            // pull out the special string_options kwarg
            object stringOptions = null;

            kwargs?.Remove("string_options", out stringOptions);
            // logger.Debug($"VipsOperation.call: stringOptions = {stringOptions}");

            var op        = NewFromName(operationName);
            var arguments = op.GetArgs();

            // logger.Debug($"VipsOperation.call: arguments = {arguments}");

            // make a thing to quickly get flags from an arg name
            var flagsFromName = new Dictionary <string, Internal.Enums.VipsArgumentFlags>();

            var nRequired = 0;

            foreach (var entry in arguments)
            {
                var name = entry.Key;
                var flag = entry.Value;

                flagsFromName[name] = flag;

                // count required input args
                if ((flag & Internal.Enums.VipsArgumentFlags.VIPS_ARGUMENT_INPUT) != 0 &&
                    (flag & Internal.Enums.VipsArgumentFlags.VIPS_ARGUMENT_REQUIRED) != 0 &&
                    (flag & Internal.Enums.VipsArgumentFlags.VIPS_ARGUMENT_DEPRECATED) == 0)
                {
                    nRequired++;
                }
            }

            if (nRequired != args.Length)
            {
                throw new ArgumentException(
                          $"unable to call {operationName}: {args.Length} arguments given, but {nRequired} required");
            }

            // the first image argument is the thing we expand constants to
            // match ... look inside tables for images, since we may be passing
            // an array of image as a single param
            var matchImage = FindInside <Image>(args);

            // logger.Debug($"VipsOperation.call: matchImage = {matchImage}");

            // 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 required and optional args
            var n = 0;

            foreach (var entry in arguments)
            {
                var name = entry.Key;
                var flag = entry.Value;

                if ((flag & Internal.Enums.VipsArgumentFlags.VIPS_ARGUMENT_INPUT) != 0 &&
                    (flag & Internal.Enums.VipsArgumentFlags.VIPS_ARGUMENT_REQUIRED) != 0 &&
                    (flag & Internal.Enums.VipsArgumentFlags.VIPS_ARGUMENT_DEPRECATED) == 0)
                {
                    op.Set(name, flag, matchImage, args[n]);
                    n++;
                }
            }

            if (kwargs != null)
            {
                foreach (var entry in kwargs)
                {
                    var name  = entry.Key;
                    var value = entry.Value;

                    if (!flagsFromName.ContainsKey(name))
                    {
                        throw new Exception($"{operationName} does not support argument {name}");
                    }

                    op.Set(name, flagsFromName[name], matchImage, value);
                }
            }

            // build operation
            var vop = VipsOperation.VipsCacheOperationBuild(op);

            if (vop == IntPtr.Zero)
            {
                throw new VipsException($"unable to call {operationName}");
            }

            op = new Operation(vop);

            // fetch required output args, plus modified input images
            var result = new List <object>();

            foreach (var entry in arguments)
            {
                var name = entry.Key;
                var flag = entry.Value;

                if ((flag & Internal.Enums.VipsArgumentFlags.VIPS_ARGUMENT_OUTPUT) != 0 &&
                    (flag & Internal.Enums.VipsArgumentFlags.VIPS_ARGUMENT_REQUIRED) != 0 &&
                    (flag & Internal.Enums.VipsArgumentFlags.VIPS_ARGUMENT_DEPRECATED) == 0)
                {
                    result.Add(op.Get(name));
                }

                if ((flag & Internal.Enums.VipsArgumentFlags.VIPS_ARGUMENT_INPUT) != 0 &&
                    (flag & Internal.Enums.VipsArgumentFlags.VIPS_ARGUMENT_MODIFY) != 0)
                {
                    result.Add(op.Get(name));
                }
            }

            // fetch optional output args
            var opts = new VOption();

            if (kwargs != null)
            {
                foreach (var entry in kwargs)
                {
                    var name = entry.Key;

                    var flags = flagsFromName[name];
                    if ((flags & Internal.Enums.VipsArgumentFlags.VIPS_ARGUMENT_OUTPUT) != 0 &&
                        (flags & Internal.Enums.VipsArgumentFlags.VIPS_ARGUMENT_REQUIRED) == 0 &&
                        (flags & Internal.Enums.VipsArgumentFlags.VIPS_ARGUMENT_DEPRECATED) == 0)
                    {
                        opts[name] = op.Get(name);
                    }
                }
            }

            Internal.VipsObject.VipsObjectUnrefOutputs(op);

            if (opts.Count > 0)
            {
                result.Add(opts);
            }

            // logger.Debug($"VipsOperation.call: result = {result}");

            return(result.Count == 0 ? null : (result.Count == 1 ? result[0] : result.ToArray()));
        }
Example #3
0
 /// <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);
Example #4
0
 /// <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));
 }
Example #5
0
 /// <summary>
 /// Call a libvips operation.
 /// </summary>
 /// <param name="image"></param>
 /// <param name="operationName"></param>
 /// <param name="kwargs"></param>
 /// <param name="args"></param>
 /// <returns></returns>
 public static object Call(this Image image, string operationName, VOption kwargs, params object[] args)
 {
     return(Operation.Call(operationName, kwargs, args.PrependImage(image)));
 }
Example #6
0
 /// <summary>
 /// Call a libvips operation.
 /// </summary>
 /// <param name="image"></param>
 /// <param name="operationName"></param>
 /// <param name="kwargs"></param>
 /// <param name="arg"></param>
 /// <returns></returns>
 public static object Call(this Image image, string operationName, VOption kwargs, object arg)
 {
     return(Operation.Call(operationName, kwargs, image, arg));
 }