public static void Dispose(AvisynthFilter filter)
        {
            var props = GetAnnotatedProperties(filter.GetType()).Select(p => p.Item1)
                        .Where(p => p.PropertyType == typeof(Clip) || p.PropertyType == typeof(Clip[]))
                        .Select(p =>
            {
                var val = p.GetGetMethod(true).Invoke(filter, null);
                p.GetSetMethod(true).Invoke(filter, new object[] { null });
                return(val);
            }).ToArray();

            props
            .OfType <Clip>().ToList()
            .ForEach(p => p?.Dispose());
            props
            .OfType <Clip[]>().SelectMany(p => p).ToList()
            .ForEach(p => p?.Dispose());
        }
Exemple #2
0
 public static void Dispose(AvisynthFilter filter)
 {
     GetAnnotatedProperties(filter.GetType()).Select(p => p.Item1).Where(p => p.PropertyType == typeof(Clip))
     .Select(p => p.GetGetMethod(true).Invoke(filter, null)).OfType <Clip>().ToList()
     .ForEach(p => p.Dispose());
 }
Exemple #3
0
        public static void InitArgs(AvisynthFilter filter, AVSValue args)
        {
            var annotatedProperties = GetAnnotatedProperties(filter.GetType());

            if (annotatedProperties.Length != args.ArraySize() && annotatedProperties.Length != args.ArraySize() - 1)
            {
                throw new AvisynthException("Instance attributes count not match to declared");
            }
            var zeroBased = annotatedProperties.Length == args.ArraySize();

            var annotatedPropertiesWithArguments = annotatedProperties.Select((p, i) => new
            {
                Argument  = args[zeroBased ? i : ++i],
                Property  = p.Item1,
                Attribute = p.Item2
            });

            var filterName = filter.GetType().Assembly
                             .GetCustomAttributes(typeof(AvisynthFilterClassAttribute), true)
                             .OfType <AvisynthFilterClassAttribute>()
                             .FirstOrDefault(p => p.FilterType == filter.GetType())
                             ?.FilterName ?? filter.GetType().Name;

            foreach (var tuple in annotatedPropertiesWithArguments)
            {
                var propertyName = $"{filterName}.{tuple.Property.Name}";
                var isDefined    = tuple.Argument.Defined();
                if (tuple.Attribute.Required && !isDefined)
                {
                    throw new AvisynthException($"{propertyName} is required but not defined");
                }
                if (!isDefined)
                {
                    continue;
                }
                var value = tuple.Argument.AsObject();
                if (!tuple.Attribute.Min.Equals(double.MinValue) && Convert.ToDouble(value) < tuple.Attribute.Min)
                {
                    throw new AvisynthException($"{propertyName} is equal to {value} but must be greater or equal to {tuple.Attribute.Min}");
                }
                if (!tuple.Attribute.Max.Equals(double.MaxValue) && Convert.ToDouble(value) > tuple.Attribute.Max)
                {
                    throw new AvisynthException($"{propertyName} is equal to {value} but must be less or equal to {tuple.Attribute.Max}");
                }
                if (tuple.Property.PropertyType.IsEnum && value is string)
                {
                    tuple.Attribute.Values = Enum.GetNames(tuple.Property.PropertyType);
                }
                if (tuple.Property.PropertyType.IsEnum && value is int)
                {
                    tuple.Attribute.Values = Enum.GetValues(tuple.Property.PropertyType).Cast <object>().Select(p => Convert.ToInt32(p).ToString()).ToArray();
                }
                if (tuple.Attribute.Values.Any() && tuple.Attribute.Values.Select(p => p.ToLower()).All(p => !p.Equals(value.ToString())))
                {
                    throw new AvisynthException($"{propertyName} is equal to '{value}' but allowed values are [{string.Join(", ", tuple.Attribute.Values)}]");
                }
                if (tuple.Property.PropertyType.IsEnum && value is string)
                {
                    value = Enum.Parse(tuple.Property.PropertyType, value.ToString(), true);
                }
                if (tuple.Property.PropertyType.IsEnum && value is int)
                {
                    value = Enum.ToObject(tuple.Property.PropertyType, value);
                }
                tuple.Property.GetSetMethod(true).Invoke(filter, new[] { value });
            }
        }
        public static void InitArgs(AvisynthFilter filter, AVSValue args)
        {
            var annotatedProperties = GetAnnotatedProperties(filter.GetType());

            if (annotatedProperties.Length != args.ArraySize() && annotatedProperties.Length != args.ArraySize() - 1)
            {
                throw new AvisynthException("Instance attributes count not match to declared");
            }
            var zeroBased = annotatedProperties.Length == args.ArraySize();

            var annotatedPropertiesWithArguments = annotatedProperties.Select((p, i) => new
            {
                Argument  = args[zeroBased ? i : ++i],
                Property  = p.Item1,
                Attribute = p.Item2
            });

            var filterName = filter.GetType().Assembly
                             .GetCustomAttributes(typeof(AvisynthFilterClassAttribute), true)
                             .OfType <AvisynthFilterClassAttribute>()
                             .FirstOrDefault(p => p.FilterType == filter.GetType())
                             ?.FilterName ?? filter.GetType().Name;

            foreach (var tuple in annotatedPropertiesWithArguments)
            {
                var propertyName = $"{filterName}.{tuple.Property.Name}";
                var isDefined    = tuple.Argument.Defined();
                if (tuple.Attribute.Required && !isDefined)
                {
                    throw new AvisynthException($"{propertyName} is required but not defined");
                }
                if (!isDefined)
                {
                    continue;
                }
                var value = tuple.Argument.AsObject();

                Func <int, Rectangle> readRect = i =>
                {
                    using var frame = ((Clip)value).GetFrame(i, DynamicEnvironment.Env);
                    var rect = Rect.FromFrame(frame);
                    return(Rectangle.FromLTRB(rect.Left, rect.Top, rect.Right, rect.Bottom));
                };

                if (tuple.Property.PropertyType == typeof(Rectangle))
                {
                    tuple.Property.GetSetMethod(true).Invoke(filter, new object[] { readRect(0) });
                    continue;
                }

                if (typeof(ICollection <Rectangle>).IsAssignableFrom(tuple.Property.PropertyType))
                {
                    var col = (ICollection <Rectangle>)Activator.CreateInstance(tuple.Property.PropertyType);

                    var clip      = value as Clip;
                    var numFrames = clip.GetVideoInfo().num_frames;
                    if (numFrames > tuple.Attribute.Max)
                    {
                        throw new AvisynthException($"{propertyName} contains {value} values but limit is {tuple.Attribute.Max}");
                    }
                    for (var i = 0; i < numFrames; i++)
                    {
                        col.Add(readRect(i));
                    }
                    tuple.Property.GetSetMethod(true).Invoke(filter, new object[] { col });
                    continue;
                }

                if (!tuple.Attribute.Min.Equals(double.MinValue) && Convert.ToDouble(value) < tuple.Attribute.Min)
                {
                    throw new AvisynthException($"{propertyName} is equal to {value} but must be greater or equal to {tuple.Attribute.Min}");
                }
                if (!tuple.Attribute.Max.Equals(double.MaxValue) && Convert.ToDouble(value) > tuple.Attribute.Max)
                {
                    throw new AvisynthException($"{propertyName} is equal to {value} but must be less or equal to {tuple.Attribute.Max}");
                }
                if (tuple.Property.PropertyType.IsEnum && value is string)
                {
                    tuple.Attribute.Values = Enum.GetNames(tuple.Property.PropertyType);
                }
                if (tuple.Property.PropertyType.IsEnum && value is int)
                {
                    tuple.Attribute.Values = Enum.GetValues(tuple.Property.PropertyType).Cast <object>().Select(p => Convert.ToInt32(p).ToString()).ToArray();
                }
                if (tuple.Attribute.Values.Any() && tuple.Attribute.Values.Select(p => p.ToLower()).All(p => !p.Equals(value.ToString())))
                {
                    throw new AvisynthException($"{propertyName} is equal to '{value}' but allowed values are [{string.Join(", ", tuple.Attribute.Values)}]");
                }
                if (tuple.Property.PropertyType.IsEnum && value is string)
                {
                    value = Enum.Parse(tuple.Property.PropertyType, value.ToString(), true);
                }
                if (tuple.Property.PropertyType.IsEnum && value is int)
                {
                    value = Enum.ToObject(tuple.Property.PropertyType, value);
                }
                tuple.Property.GetSetMethod(true).Invoke(filter, new[] { value });
            }
        }