diff --git a/GenericImage/Common/Helpers/Class.cs b/GenericImage/Common/Helpers/Class.cs deleted file mode 100644 index ad446739ac..0000000000 --- a/GenericImage/Common/Helpers/Class.cs +++ /dev/null @@ -1,58 +0,0 @@ -namespace GenericImage.Helpers -{ - interface INullOp - { - bool HasValue(T value); - bool AddIfNotNull(ref T accumulator, T value); - } - sealed class StructNullOp - : INullOp, INullOp - where T : struct - { - public bool HasValue(T value) - { - return true; - } - public bool AddIfNotNull(ref T accumulator, T value) - { - accumulator = Operator.Add(accumulator, value); - return true; - } - public bool HasValue(T? value) - { - return value.HasValue; - } - public bool AddIfNotNull(ref T? accumulator, T? value) - { - if (value.HasValue) - { - accumulator = accumulator.HasValue ? - Operator.Add( - accumulator.GetValueOrDefault(), - value.GetValueOrDefault()) - : value; - return true; - } - return false; - } - } - sealed class ClassNullOp - : INullOp - where T : class - { - public bool HasValue(T value) - { - return value != null; - } - public bool AddIfNotNull(ref T accumulator, T value) - { - if (value != null) - { - accumulator = accumulator == null ? - value : Operator.Add(accumulator, value); - return true; - } - return false; - } - } -} diff --git a/GenericImage/Common/Helpers/ExpressionUtil.cs b/GenericImage/Common/Helpers/ExpressionUtil.cs deleted file mode 100644 index fc66742a01..0000000000 --- a/GenericImage/Common/Helpers/ExpressionUtil.cs +++ /dev/null @@ -1,100 +0,0 @@ -namespace GenericImage.Helpers -{ - using System; - using System.Linq.Expressions; - - /// - /// General purpose Expression utilities - /// - public static class ExpressionUtil - { - /// - /// Create a function delegate representing a unary operation - /// - /// The parameter type - /// The return type - /// Body factory - /// Compiled function delegate - public static Func CreateExpression( - Func body) - { - ParameterExpression inp = Expression.Parameter(typeof(TArg1), "inp"); - try - { - return Expression.Lambda>(body(inp), inp).Compile(); - } - catch (Exception ex) - { - string msg = ex.Message; // avoid capture of ex itself - return delegate { throw new InvalidOperationException(msg); }; - } - } - - /// - /// Create a function delegate representing a binary operation - /// - /// The first parameter type - /// The second parameter type - /// The return type - /// Body factory - /// Compiled function delegate - public static Func CreateExpression( - Func body) - { - return CreateExpression(body, false); - } - - /// - /// Create a function delegate representing a binary operation - /// - /// - /// If no matching operation is possible, attempt to convert - /// TArg1 and TArg2 to TResult for a match? For example, there is no - /// "decimal operator /(decimal, int)", but by converting TArg2 (int) to - /// TResult (decimal) a match is found. - /// - /// The first parameter type - /// The second parameter type - /// The return type - /// Body factory - /// Compiled function delegate - public static Func CreateExpression( - Func body, bool castArgsToResultOnFailure) - { - ParameterExpression lhs = Expression.Parameter(typeof(TArg1), "lhs"); - ParameterExpression rhs = Expression.Parameter(typeof(TArg2), "rhs"); - try - { - try - { - return Expression.Lambda>(body(lhs, rhs), lhs, rhs).Compile(); - } - catch (InvalidOperationException) - { - // If we show retry and the args aren't already "TValue, TValue, TValue"... - // convert both lhs and rhs to TResult (as appropriate) - if (castArgsToResultOnFailure && !(typeof(TArg1) == typeof(TResult) && typeof(TArg2) == typeof(TResult))) - { - Expression castLhs = typeof(TArg1) == typeof(TResult) - ? lhs - : (Expression)Expression.Convert(lhs, typeof(TResult)); - - Expression castRhs = typeof(TArg2) == typeof(TResult) - ? rhs - : (Expression)Expression.Convert(rhs, typeof(TResult)); - - return Expression.Lambda>( - body(castLhs, castRhs), lhs, rhs).Compile(); - } - - throw; - } - } - catch (Exception ex) - { - string msg = ex.Message; // avoid capture of ex itself - return delegate { throw new InvalidOperationException(msg); }; - } - } - } -} diff --git a/GenericImage/Common/Helpers/ImageMaths.cs b/GenericImage/Common/Helpers/ImageMaths.cs deleted file mode 100644 index 2c5e4f884a..0000000000 --- a/GenericImage/Common/Helpers/ImageMaths.cs +++ /dev/null @@ -1,40 +0,0 @@ -namespace GenericImage -{ - public static class ImageMaths - { - /// - /// Restricts a value to be within a specified range. - /// - /// The value to clamp. - /// The minimum value. If value is less than min, min will be returned. - /// The maximum value. If value is greater than max, max will be returned. - /// The clamped value. - public static float Clamp(float value, float min, float max) - { - // This compare order is very important!!! - // We must follow HLSL behavior in the case user specified min value is bigger than max value. - // First we check to see if we're greater than the max - value = (value > max) ? max : value; - - // Then we check to see if we're less than the min. - value = (value < min) ? min : value; - - // There's no check to see if min > max. - return value; - } - - /// - /// Restricts a value to be within a specified range. - /// - /// The value to clamp. - /// The minimum value. If value is less than min, min will be returned. - /// The maximum value. If value is greater than max, max will be returned. - /// The clamped value. - public static int Clamp(int value, int min, int max) - { - value = (value > max) ? max : value; - value = (value < min) ? min : value; - return value; - } - } -} diff --git a/GenericImage/Common/Helpers/Operator.cs b/GenericImage/Common/Helpers/Operator.cs deleted file mode 100644 index 872eb3abe9..0000000000 --- a/GenericImage/Common/Helpers/Operator.cs +++ /dev/null @@ -1,479 +0,0 @@ -namespace GenericImage.Helpers -{ - using System; - using System.Linq.Expressions; - using System.Reflection; - - /// - /// The Operator class provides easy access to the standard operators - /// (addition, etc) for generic types, using type inference to simplify - /// usage. - /// - public static class Operator - { - - /// - /// Indicates if the supplied value is non-null, - /// for reference-types or Nullable<T> - /// - /// True for non-null values, else false - public static bool HasValue(T value) - { - - return Operator.NullOp.HasValue(value); - - } - - /// - /// Increments the accumulator only - /// if the value is non-null. If the accumulator - /// is null, then the accumulator is given the new - /// value; otherwise the accumulator and value - /// are added. - /// - /// The current total to be incremented (can be null) - /// The value to be tested and added to the accumulator - /// True if the value is non-null, else false - i.e. - /// "has the accumulator been updated?" - public static bool AddIfNotNull(ref T accumulator, T value) - { - return Operator.NullOp.AddIfNotNull(ref accumulator, value); - } - - /// - /// Evaluates unary negation (-) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T Negate(T value) - { - return Operator.Negate(value); - } - /// - /// Evaluates bitwise not (~) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T Not(T value) - { - return Operator.Not(value); - } - /// - /// Evaluates bitwise or (|) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T Or(T value1, T value2) - { - return Operator.Or(value1, value2); - } - /// - /// Evaluates bitwise and (&) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T And(T value1, T value2) - { - return Operator.And(value1, value2); - } - /// - /// Evaluates bitwise xor (^) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T Xor(T value1, T value2) - { - return Operator.Xor(value1, value2); - } - /// - /// Performs a conversion between the given types; this will throw - /// an InvalidOperationException if the type T does not provide a suitable cast, or for - /// Nullable<TInner> if TInner does not provide this cast. - /// - public static TTo Convert(TFrom value) - { - return Operator.Convert(value); - } - /// - /// Evaluates binary addition (+) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T Add(T value1, T value2) - { - return Operator.Add(value1, value2); - } - /// - /// Evaluates binary addition (+) for the given type(s); this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static TArg1 AddAlternative(TArg1 value1, TArg2 value2) - { - return Operator.Add(value1, value2); - } - /// - /// Evaluates binary subtraction (-) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T Subtract(T value1, T value2) - { - return Operator.Subtract(value1, value2); - } - /// - /// Evaluates binary subtraction(-) for the given type(s); this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static TArg1 SubtractAlternative(TArg1 value1, TArg2 value2) - { - return Operator.Subtract(value1, value2); - } - /// - /// Evaluates binary multiplication (*) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T Multiply(T value1, T value2) - { - return Operator.Multiply(value1, value2); - } - /// - /// Evaluates binary multiplication (*) for the given type(s); this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static TArg1 MultiplyAlternative(TArg1 value1, TArg2 value2) - { - return Operator.Multiply(value1, value2); - } - /// - /// Evaluates binary division (/) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T Divide(T value1, T value2) - { - return Operator.Divide(value1, value2); - } - /// - /// Evaluates binary division (/) for the given type(s); this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static TArg1 DivideAlternative(TArg1 value1, TArg2 value2) - { - return Operator.Divide(value1, value2); - } - /// - /// Evaluates binary equality (==) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static bool Equal(T value1, T value2) - { - return Operator.Equal(value1, value2); - } - /// - /// Evaluates binary inequality (!=) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static bool NotEqual(T value1, T value2) - { - return Operator.NotEqual(value1, value2); - } - /// - /// Evaluates binary greater-than (>) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static bool GreaterThan(T value1, T value2) - { - return Operator.GreaterThan(value1, value2); - } - /// - /// Evaluates binary less-than (<) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static bool LessThan(T value1, T value2) - { - return Operator.LessThan(value1, value2); - } - /// - /// Evaluates binary greater-than-on-eqauls (>=) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static bool GreaterThanOrEqual(T value1, T value2) - { - return Operator.GreaterThanOrEqual(value1, value2); - } - /// - /// Evaluates binary less-than-or-equal (<=) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static bool LessThanOrEqual(T value1, T value2) - { - return Operator.LessThanOrEqual(value1, value2); - } - /// - /// Evaluates integer division (/) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - /// This operation is particularly useful for computing averages and - /// similar aggregates. - /// - public static T DivideInt32(T value, int divisor) - { - return Operator.Divide(value, divisor); - } - } - /// - /// Provides standard operators (such as addition) that operate over operands of - /// different types. For operators, the return type is assumed to match the first - /// operand. - /// - /// - /// - public static class Operator - { - private static readonly Func convert; - /// - /// Returns a delegate to convert a value between two types; this delegate will throw - /// an InvalidOperationException if the type T does not provide a suitable cast, or for - /// Nullable<TInner> if TInner does not provide this cast. - /// - public static Func Convert => convert; - - static Operator() - { - convert = ExpressionUtil.CreateExpression(body => Expression.Convert(body, typeof(TResult))); - add = ExpressionUtil.CreateExpression(Expression.Add, true); - subtract = ExpressionUtil.CreateExpression(Expression.Subtract, true); - multiply = ExpressionUtil.CreateExpression(Expression.Multiply, true); - divide = ExpressionUtil.CreateExpression(Expression.Divide, true); - } - - private static readonly Func add, subtract, multiply, divide; - - private static readonly Func multiplyF, divideF; - - /// - /// Returns a delegate to evaluate binary addition (+) for the given types; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Add => add; - - /// - /// Returns a delegate to evaluate binary subtraction (-) for the given types; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Subtract => subtract; - - /// - /// Returns a delegate to evaluate binary multiplication (*) for the given types; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Multiply => multiply; - - /// - /// Returns a delegate to evaluate binary division (/) for the given types; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Divide => divide; - - public static Func MultiplyF => multiplyF; - - public static Func DivideF => divideF; - } - - /// - /// Provides standard operators (such as addition) over a single type - /// - /// - /// - public static class Operator - { - static readonly INullOp nullOp; - internal static INullOp NullOp => nullOp; - - static readonly T zero; - /// - /// Returns the zero value for value-types (even full Nullable<TInner>) - or null for reference types - /// - public static T Zero => zero; - - static readonly Func negate, not; - static readonly Func or, and, xor; - /// - /// Returns a delegate to evaluate unary negation (-) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Negate => negate; - - /// - /// Returns a delegate to evaluate bitwise not (~) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Not => not; - - /// - /// Returns a delegate to evaluate bitwise or (|) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Or => or; - - /// - /// Returns a delegate to evaluate bitwise and (&) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func And => and; - - /// - /// Returns a delegate to evaluate bitwise xor (^) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Xor => xor; - - static readonly Func add, subtract, multiply, divide; - - static readonly Func multiplyF, divideF; - - /// - /// Returns a delegate to evaluate binary addition (+) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Add => add; - - /// - /// Returns a delegate to evaluate binary subtraction (-) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Subtract => subtract; - - /// - /// Returns a delegate to evaluate binary multiplication (*) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Multiply => multiply; - - /// - /// Returns a delegate to evaluate binary division (/) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Divide => divide; - - public static Func MultiplyF => multiplyF; - - public static Func DivideF => divideF; - - static readonly Func equal, notEqual, greaterThan, lessThan, greaterThanOrEqual, lessThanOrEqual; - - /// - /// Returns a delegate to evaluate binary equality (==) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Equal => equal; - - /// - /// Returns a delegate to evaluate binary inequality (!=) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func NotEqual => notEqual; - - /// - /// Returns a delegate to evaluate binary greater-then (>) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func GreaterThan => greaterThan; - - /// - /// Returns a delegate to evaluate binary less-than (<) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func LessThan => lessThan; - - /// - /// Returns a delegate to evaluate binary greater-than-or-equal (>=) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func GreaterThanOrEqual => greaterThanOrEqual; - - /// - /// Returns a delegate to evaluate binary less-than-or-equal (<=) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func LessThanOrEqual => lessThanOrEqual; - - static Operator() - { - add = ExpressionUtil.CreateExpression(Expression.Add); - subtract = ExpressionUtil.CreateExpression(Expression.Subtract); - divide = ExpressionUtil.CreateExpression(Expression.Divide); - multiply = ExpressionUtil.CreateExpression(Expression.Multiply); - multiplyF = ExpressionUtil.CreateExpression(Expression.Multiply); - divideF = ExpressionUtil.CreateExpression(Expression.Multiply); - - greaterThan = ExpressionUtil.CreateExpression(Expression.GreaterThan); - greaterThanOrEqual = ExpressionUtil.CreateExpression(Expression.GreaterThanOrEqual); - lessThan = ExpressionUtil.CreateExpression(Expression.LessThan); - lessThanOrEqual = ExpressionUtil.CreateExpression(Expression.LessThanOrEqual); - equal = ExpressionUtil.CreateExpression(Expression.Equal); - notEqual = ExpressionUtil.CreateExpression(Expression.NotEqual); - - negate = ExpressionUtil.CreateExpression(Expression.Negate); - and = ExpressionUtil.CreateExpression(Expression.And); - or = ExpressionUtil.CreateExpression(Expression.Or); - not = ExpressionUtil.CreateExpression(Expression.Not); - xor = ExpressionUtil.CreateExpression(Expression.ExclusiveOr); - - Type typeT = typeof(T); - if (typeT.GetTypeInfo().IsValueType && typeT.GetTypeInfo().IsGenericType && (typeT.GetGenericTypeDefinition() == typeof(Nullable<>))) - { - // get the *inner* zero (not a null Nullable, but default(TValue)) - Type nullType = typeT.GetTypeInfo().GenericTypeArguments[0]; - zero = (T)Activator.CreateInstance(nullType); - nullOp = (INullOp)Activator.CreateInstance( - typeof(StructNullOp<>).MakeGenericType(nullType)); - } - else - { - zero = default(T); - if (typeT.GetTypeInfo().IsValueType) - { - nullOp = (INullOp)Activator.CreateInstance( - typeof(StructNullOp<>).MakeGenericType(typeT)); - } - else - { - nullOp = (INullOp)Activator.CreateInstance( - typeof(ClassNullOp<>).MakeGenericType(typeT)); - } - } - } - } -} diff --git a/GenericImage/GenericImage.xproj b/GenericImage/GenericImage.xproj deleted file mode 100644 index 9ffcf72232..0000000000 --- a/GenericImage/GenericImage.xproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - 45d91211-9d4a-4382-a114-8786859e302a - GenericImage - .\obj - .\bin\ - v4.5.2 - - - - 2.0 - - - diff --git a/GenericImage/IImageBase.cs b/GenericImage/IImageBase.cs deleted file mode 100644 index d5dac55168..0000000000 --- a/GenericImage/IImageBase.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace GenericImage -{ - using GenericImage.PackedVectors; - - public interface IImageBase - where TColor : IColor - where TDepth : struct - { - TColor[] Pixels { get; } - - int Width { get; } - - int Height { get; } - - IPixelAccessor Lock(); - } -} diff --git a/GenericImage/IImageProcessor.cs b/GenericImage/IImageProcessor.cs deleted file mode 100644 index 68aecb3be8..0000000000 --- a/GenericImage/IImageProcessor.cs +++ /dev/null @@ -1,76 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace GenericImage -{ - using PackedVectors; - - /// - /// A delegate which is called as progress is made processing an image. - /// - /// The source of the event. - /// An object that contains the event data. - public delegate void ProgressEventHandler(object sender, ProgressEventArgs e); - - /// - /// Encapsulates methods to alter the pixels of an image. - /// - public interface IImageProcessor - { - /// - /// Event fires when each row of the source image has been processed. - /// - /// - /// This event may be called from threads other than the client thread, and from multiple threads simultaneously. - /// Individual row notifications may arrived out of order. - /// - event ProgressEventHandler OnProgress; - - /// - /// Applies the process to the specified portion of the specified . - /// - /// The type of pixels contained within the image. - /// Target image to apply the process to. - /// The source image. Cannot be null. - /// - /// The structure that specifies the portion of the image object to draw. - /// - /// - /// The method keeps the source image unchanged and returns the - /// the result of image processing filter as new image. - /// - /// - /// is null or is null. - /// - /// - /// doesnt fit the dimension of the image. - /// - void Apply(ImageBase target, ImageBase source, Rectangle sourceRectangle) - where TColor : IColor, new() where TDepth : struct; - - /// - /// Applies the process to the specified portion of the specified at the specified - /// location and with the specified size. - /// - /// The type of pixels contained within the image. - /// Target image to apply the process to. - /// The source image. Cannot be null. - /// The target width. - /// The target height. - /// - /// The structure that specifies the location and size of the drawn image. - /// The image is scaled to fit the rectangle. - /// - /// - /// The structure that specifies the portion of the image object to draw. - /// - /// - /// The method keeps the source image unchanged and returns the - /// the result of image process as new image. - /// - void Apply(ImageBase target, ImageBase source, int width, int height, Rectangle targetRectangle, Rectangle sourceRectangle) - where TColor : IColor, new() where TDepth : struct; - } -} diff --git a/GenericImage/IPixelAccessor.cs b/GenericImage/IPixelAccessor.cs deleted file mode 100644 index 3ef5887916..0000000000 --- a/GenericImage/IPixelAccessor.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace GenericImage -{ - using System; - - public interface IPixelAccessor : IDisposable - { - TColor this[int x, int y] - { - get; - set; - } - - /// - /// Gets the width. - /// - int Width { get; } - - /// - /// Gets the height. - /// - int Height { get; } - } -} diff --git a/GenericImage/ImageBase.cs b/GenericImage/ImageBase.cs deleted file mode 100644 index e8052d36ca..0000000000 --- a/GenericImage/ImageBase.cs +++ /dev/null @@ -1,190 +0,0 @@ -namespace GenericImage -{ - using System; - - using GenericImage.PackedVectors; - - /// - /// Encapsulates the basic properties and methods required to manipulate images - /// in different pixel formats. - /// - /// The packed vector pixels format. - /// The bit depth of the image. byte, float, etc. - public abstract class ImageBase : IImageBase - where TColor : IColor - where TDepth : struct - { - /// - /// Initializes a new instance of the class. - /// - protected ImageBase() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The width of the image in pixels. - /// The height of the image in pixels. - /// - /// Thrown if either or are less than or equal to 0. - /// - protected ImageBase(int width, int height) - { - // Guard.MustBeGreaterThan(width, 0, nameof(width)); - // Guard.MustBeGreaterThan(height, 0, nameof(height)); - - this.Width = width; - this.Height = height; - this.Pixels = new TColor[width * height]; - } - - /// - /// Initializes a new instance of the class. - /// - /// - /// The other to create this instance from. - /// - /// - /// Thrown if the given is null. - /// - protected ImageBase(ImageBase other) - { - // Guard.NotNull(other, nameof(other), "Other image cannot be null."); - - this.Width = other.Width; - this.Height = other.Height; - this.Quality = other.Quality; - this.FrameDelay = other.FrameDelay; - - // Copy the pixels. - this.Pixels = new TColor[this.Width * this.Height]; - Array.Copy(other.Pixels, this.Pixels, other.Pixels.Length); - } - - /// - /// Gets the pixels as an array of the given packed pixel format. - /// - public TColor[] Pixels { get; private set; } - - /// - /// Gets the width in pixels. - /// - public int Width { get; private set; } - - /// - /// Gets the height in pixels. - /// - public int Height { get; private set; } - - /// - /// Gets the pixel ratio made up of the width and height. - /// - public double PixelRatio => (double)this.Width / this.Height; - - /// - /// Gets the representing the bounds of the image. - /// - // public Rectangle Bounds => new Rectangle(0, 0, this.Width, this.Height); - - /// - /// Gets or sets th quality of the image. This affects the output quality of lossy image formats. - /// - public int Quality { get; set; } - - /// - /// Gets or sets the frame delay for animated images. - /// If not 0, this field specifies the number of hundredths (1/100) of a second to - /// wait before continuing with the processing of the Data Stream. - /// The clock starts ticking immediately after the graphic is rendered. - /// - public int FrameDelay { get; set; } - - - - /// - /// Sets the pixel array of the image to the given value. - /// - /// The new width of the image. Must be greater than zero. - /// The new height of the image. Must be greater than zero. - /// - /// The array with colors. Must be a multiple of the width and height. - /// - /// - /// Thrown if either or are less than or equal to 0. - /// - /// - /// Thrown if the length is not equal to Width * Height. - /// - public void SetPixels(int width, int height, TColor[] pixels) - { - if (width <= 0) - { - throw new ArgumentOutOfRangeException(nameof(width), "Width must be greater than or equals than zero."); - } - - if (height <= 0) - { - throw new ArgumentOutOfRangeException(nameof(height), "Height must be greater than or equal than zero."); - } - - if (pixels.Length != width * height) - { - throw new ArgumentException("Pixel array must have the length of Width * Height."); - } - - this.Width = width; - this.Height = height; - this.Pixels = pixels; - } - - /// - /// Sets the pixel array of the image to the given value, creating a copy of - /// the original pixels. - /// - /// The new width of the image. Must be greater than zero. - /// The new height of the image. Must be greater than zero. - /// - /// The array with colors. Must be a multiple of four times the width and height. - /// - /// - /// Thrown if either or are less than or equal to 0. - /// - /// - /// Thrown if the length is not equal to Width * Height. - /// - public void ClonePixels(int width, int height, TColor[] pixels) - { - if (width <= 0) - { - throw new ArgumentOutOfRangeException(nameof(width), "Width must be greater than or equals than zero."); - } - - if (height <= 0) - { - throw new ArgumentOutOfRangeException(nameof(height), "Height must be greater than or equal than zero."); - } - - if (pixels.Length != width * height) - { - throw new ArgumentException("Pixel array must have the length of Width * Height."); - } - - this.Width = width; - this.Height = height; - - // Copy the pixels. - this.Pixels = new TColor[pixels.Length]; - Array.Copy(pixels, this.Pixels, pixels.Length); - } - - /// - /// Locks the image providing access to the pixels. - /// - /// It is imperative that the accessor is correctly disposed off after use. - /// - /// - /// The - public abstract IPixelAccessor Lock(); - } -} diff --git a/GenericImage/ImageProcessor.cs b/GenericImage/ImageProcessor.cs deleted file mode 100644 index 18f4966206..0000000000 --- a/GenericImage/ImageProcessor.cs +++ /dev/null @@ -1,165 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace GenericImage -{ - using System; - using System.Threading; - - using GenericImage.PackedVectors; - - /// - /// Allows the application of processors to images. - /// - public abstract class ImageProcessor : IImageProcessor - { - /// - public event ProgressEventHandler OnProgress; - - /// - /// The number of rows processed by a derived class. - /// - private int numRowsProcessed; - - /// - /// The total number of rows that will be processed by a derived class. - /// - private int totalRows; - - /// - public void Apply(ImageBase target, ImageBase source, Rectangle sourceRectangle) - where TColor : IColor, new() where TDepth : struct - { - try - { - this.OnApply(target, source, target.Bounds, sourceRectangle); - - this.numRowsProcessed = 0; - this.totalRows = sourceRectangle.Height; - - this.Apply(target, source, target.Bounds, sourceRectangle, sourceRectangle.Y, sourceRectangle.Bottom); - - this.AfterApply(target, source, target.Bounds, sourceRectangle); - } - catch (Exception ex) - { - - throw new ImageProcessingException($"An error occured when processing the image using {this.GetType().Name}. See the inner exception for more detail.", ex); - } - } - - /// - public void Apply(ImageBase target, ImageBase source, int width, int height, Rectangle targetRectangle, Rectangle sourceRectangle) where TColor : IColor, new() where TDepth : struct - { - try - { - TColor[] pixels = new TColor[width * height]; - target.SetPixels(width, height, pixels); - - // Ensure we always have bounds. - if (sourceRectangle == Rectangle.Empty) - { - sourceRectangle = source.Bounds; - } - - if (targetRectangle == Rectangle.Empty) - { - targetRectangle = target.Bounds; - } - - this.OnApply(target, source, targetRectangle, sourceRectangle); - - this.numRowsProcessed = 0; - this.totalRows = targetRectangle.Height; - - this.Apply(target, source, targetRectangle, sourceRectangle, targetRectangle.Y, targetRectangle.Bottom); - - this.AfterApply(target, source, target.Bounds, sourceRectangle); - } - catch (Exception ex) - { - throw new ImageProcessingException($"An error occured when processing the image using {this.GetType().Name}. See the inner exception for more detail.", ex); - } - } - - /// - /// This method is called before the process is applied to prepare the processor. - /// - /// Target image to apply the process to. - /// The source image. Cannot be null. - /// - /// The structure that specifies the location and size of the drawn image. - /// The image is scaled to fit the rectangle. - /// - /// - /// The structure that specifies the portion of the image object to draw. - /// - protected virtual void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) - where TColor : IColor, new() where TDepth : struct - { - } - - /// - /// Applies the process to the specified portion of the specified at the specified location - /// and with the specified size. - /// - /// The type of pixels contained within the image. - /// Target image to apply the process to. - /// The source image. Cannot be null. - /// - /// The structure that specifies the location and size of the drawn image. - /// The image is scaled to fit the rectangle. - /// - /// - /// The structure that specifies the portion of the image object to draw. - /// - /// The index of the row within the source image to start processing. - /// The index of the row within the source image to end processing. - /// - /// The method keeps the source image unchanged and returns the - /// the result of image process as new image. - /// - protected abstract void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) - where TColor : IColor, new() where TDepth : struct; - - /// - /// This method is called after the process is applied to prepare the processor. - /// - /// The type of pixels contained within the image. - /// Target image to apply the process to. - /// The source image. Cannot be null. - /// - /// The structure that specifies the location and size of the drawn image. - /// The image is scaled to fit the rectangle. - /// - /// - /// The structure that specifies the portion of the image object to draw. - /// - protected virtual void AfterApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) - where TColor : IColor, new() where TDepth : struct - { - } - - /// - /// Must be called by derived classes after processing a single row. - /// - protected void OnRowProcessed() - { - if (this.OnProgress != null) - { - int currThreadNumRows = Interlocked.Add(ref this.numRowsProcessed, 1); - - // Multi-pass filters process multiple times more rows than totalRows, so update totalRows on the fly - if (currThreadNumRows > this.totalRows) - { - this.totalRows = currThreadNumRows; - } - - // Report progress. This may be on the client's thread, or on a Task library thread. - this.OnProgress(this, new ProgressEventArgs { RowsProcessed = currThreadNumRows, TotalRows = this.totalRows }); - } - } - } -} diff --git a/GenericImage/ImageRgba32.cs b/GenericImage/ImageRgba32.cs deleted file mode 100644 index c5a48d0f93..0000000000 --- a/GenericImage/ImageRgba32.cs +++ /dev/null @@ -1,13 +0,0 @@ -namespace GenericImage -{ - using GenericImage.PackedVectors; - - public class ImageRgba32 : ImageBase - { - /// - public override IPixelAccessor Lock() - { - return new PixelAccessorRgba32(this); - } - } -} diff --git a/GenericImage/ImageRgba64.cs b/GenericImage/ImageRgba64.cs deleted file mode 100644 index 9e58bf7819..0000000000 --- a/GenericImage/ImageRgba64.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace GenericImage -{ - using GenericImage.PackedVectors; - - public class ImageRgba64 : IImageBase - { - public ImageRgba64(int width, int height) - { - this.Width = width; - this.Height = height; - this.Pixels = new Rgba64[width * height]; - } - - public Rgba64[] Pixels { get; } - - public int Width { get; } - - public int Height { get; } - - public IPixelAccessor Lock() - { - return new PixelAccessorRgba64(this); - } - } -} diff --git a/GenericImage/PackedVectors/Bgra.cs b/GenericImage/PackedVectors/Bgra.cs deleted file mode 100644 index dadc844c0e..0000000000 --- a/GenericImage/PackedVectors/Bgra.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Numerics; - -using GenericImage.Helpers; -using GenericImage.PackedVectors; - -namespace GenericImage.PackedVectors -{ - public struct Bgra : IColor - where TDepth : struct - { - private static readonly TDepth[] Components = new TDepth[4]; - - public TDepth[] Values => Components; - - public void Add(TColor value) where TColor : IColor - { - for (int i = 0; i < value.Values.Length; i++) - { - this.Values[i] = Operator.Add(this.Values[i], value.Values[i]); - } - } - - public void Multiply(TColor value) where TColor : IColor - { - for (int i = 0; i < value.Values.Length; i++) - { - this.Values[i] = Operator.Multiply(this.Values[i], value.Values[i]); - } - } - - public void Multiply(float value) where TColor : IColor - { - for (int i = 0; i < this.Values.Length; i++) - { - this.Values[i] = Operator.MultiplyF(this.Values[i], value); - } - } - - public void Divide(TColor value) where TColor : IColor - { - for (int i = 0; i < value.Values.Length; i++) - { - this.Values[i] = Operator.Divide(this.Values[i], value.Values[i]); - } - } - - public void Divide(float value) where TColor : IColor - { - for (int i = 0; i < this.Values.Length; i++) - { - this.Values[i] = Operator.DivideF(this.Values[i], value); - } - } - - public byte[] ToBytes() - { - if (typeof(TDepth) == typeof(byte)) - { - return new[] - { - (byte)(object)this.Values[0], - (byte)(object)this.Values[1], - (byte)(object)this.Values[2], - (byte)(object)this.Values[3] - }; - } - - return null; - } - - public void FromBytes(byte[] bytes) - { - if (bytes.Length != 4) - { - throw new ArgumentOutOfRangeException(nameof(bytes)); - } - - for (int i = 0; i < bytes.Length; i++) - { - this.Values[i] = (TDepth)(object)bytes[i]; - } - } - } -} diff --git a/GenericImage/PackedVectors/IColor.cs b/GenericImage/PackedVectors/IColor.cs deleted file mode 100644 index 69924e47f9..0000000000 --- a/GenericImage/PackedVectors/IColor.cs +++ /dev/null @@ -1,42 +0,0 @@ -namespace GenericImage.PackedVectors -{ - using System.Numerics; - - public interface IColor4 : IColor - where T : struct - { - T X { get; set; } - - T Y { get; set; } - - T Z { get; set; } - - T W { get; set; } - } - - public interface IColor : IColor - where TDepth : struct - { - TDepth[] Values { get; } - - void Add(TColor value) where TColor : IColor; - - void Multiply(TColor value) where TColor : IColor; - - void Multiply(float value) where TColor : IColor; - - void Divide(TColor value) where TColor : IColor; - - void Divide(float value) where TColor : IColor; - - void FromBytes(byte[] bytes); - - byte[] ToBytes(); - } - - public interface IColor - { - - - } -} diff --git a/GenericImage/PackedVectors/IPackedVector.cs b/GenericImage/PackedVectors/IPackedVector.cs deleted file mode 100644 index 860409ba21..0000000000 --- a/GenericImage/PackedVectors/IPackedVector.cs +++ /dev/null @@ -1,53 +0,0 @@ -namespace GenericImage.PackedVectors -{ - using System.Numerics; - - /// - /// An interface that converts packed vector types to and from values, - /// allowing multiple encodings to be manipulated in a generic way. - /// - /// - /// The type of object representing the packed value. - /// - public interface IPackedVector : IPackedVector - where TPacked : struct - { - /// - /// Gets or sets the packed representation of the value. - /// - TPacked PackedValue { get; set; } - } - - /// - /// An interface that converts packed vector types to and from values. - /// - public interface IPackedVector - { - /// - /// Sets the packed representation from a . - /// - /// The vector to pack. - void PackVector(Vector4 vector); - - /// - /// Sets the packed representation from a . - /// - /// The x-component. - /// The y-component. - /// The z-component. - /// The w-component. - void PackBytes(byte x, byte y, byte z, byte w); - - /// - /// Expands the packed representation into a . - /// - /// The . - Vector4 ToVector4(); - - /// - /// Expands the packed representation into a . - /// - /// The . - byte[] ToBytes(); - } -} diff --git a/GenericImage/PackedVectors/Rgba32.cs b/GenericImage/PackedVectors/Rgba32.cs deleted file mode 100644 index 1786b36814..0000000000 --- a/GenericImage/PackedVectors/Rgba32.cs +++ /dev/null @@ -1,163 +0,0 @@ -namespace GenericImage.PackedVectors -{ - using System; - using System.Numerics; - - /// - /// Packed vector type containing four 8-bit unsigned normalized values ranging from 0 to 1. - /// - public struct Rgba32 : IPackedVector, IEquatable - { - /// - /// Initializes a new instance of the struct. - /// - /// The red component. - /// The green component. - /// The blue component. - /// The alpha component. - public Rgba32(float r, float g, float b, float a) - { - Vector4 clamped = Vector4.Clamp(new Vector4(r, g, b, a), Vector4.Zero, Vector4.One) * 255f; - this.PackedValue = Pack(ref clamped); - } - - /// - /// Initializes a new instance of the struct. - /// - /// - /// The vector containing the components for the packed vector. - /// - public Rgba32(Vector4 vector) - { - Vector4 clamped = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * 255f; - this.PackedValue = Pack(ref clamped); - } - - /// - public uint PackedValue { get; set; } - - /// - /// Compares two objects for equality. - /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// - /// - /// True if the current left is equal to the parameter; otherwise, false. - /// - public static bool operator ==(Rgba32 left, Rgba32 right) - { - return left.PackedValue == right.PackedValue; - } - - /// - /// Compares two objects for equality. - /// - /// The on the left side of the operand. - /// The on the right side of the operand. - /// - /// True if the current left is equal to the parameter; otherwise, false. - /// - public static bool operator !=(Rgba32 left, Rgba32 right) - { - return left.PackedValue != right.PackedValue; - } - - /// - public void PackVector(Vector4 vector) - { - Vector4 clamped = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * 255f; - this.PackedValue = Pack(ref clamped); - } - - /// - public void PackBytes(byte x, byte y, byte z, byte w) - { - Vector4 vector = new Vector4(x, y, z, w); - this.PackedValue = Pack(ref vector); - } - - /// - public Vector4 ToVector4() - { - return new Vector4( - (this.PackedValue >> 16) & 0xFF, - (this.PackedValue >> 8) & 0xFF, - this.PackedValue & 0xFF, - (this.PackedValue >> 24) & 0xFF) / 255f; - } - - /// - public byte[] ToBytes() - { - return new[] - { - (byte)((this.PackedValue >> 16) & 0xFF), - (byte)((this.PackedValue >> 8) & 0xFF), - (byte)(this.PackedValue & 0xFF), - (byte)((this.PackedValue >> 24) & 0xFF) - }; - } - - /// - public override bool Equals(object obj) - { - return (obj is Rgba32) && this.Equals((Rgba32)obj); - } - - /// - public bool Equals(Rgba32 other) - { - return this.PackedValue == other.PackedValue; - } - - /// - /// Gets a string representation of the packed vector. - /// - /// A string representation of the packed vector. - public override string ToString() - { - return this.ToVector4().ToString(); - } - - /// - public override int GetHashCode() - { - return this.GetHashCode(this); - } - - /// - /// Sets the packed representation from the given component values. - /// - /// - /// The vector containing the components for the packed vector. - /// - /// - /// The . - /// - private static uint Pack(ref Vector4 vector) - { - return ((uint)Math.Round(vector.X) << 16) | - ((uint)Math.Round(vector.Y) << 8) | - (uint)Math.Round(vector.Z) | - ((uint)Math.Round(vector.W) << 24); - } - - /// - /// Returns the hash code for this instance. - /// - /// - /// The instance of to return the hash code for. - /// - /// - /// A 32-bit signed integer that is the hash code for this instance. - /// - private int GetHashCode(Rgba32 packed) - { - return packed.PackedValue.GetHashCode(); - } - } -} diff --git a/GenericImage/PackedVectors/Rgba64.cs b/GenericImage/PackedVectors/Rgba64.cs deleted file mode 100644 index f62eeb4de8..0000000000 --- a/GenericImage/PackedVectors/Rgba64.cs +++ /dev/null @@ -1,163 +0,0 @@ -namespace GenericImage.PackedVectors -{ - using System; - using System.Numerics; - - /// - /// Packed vector type containing four 16-bit unsigned normalized values ranging from 0 to 1. - /// - public struct Rgba64 : IPackedVector, IEquatable - { - /// - /// Initializes a new instance of the struct. - /// - /// The red component. - /// The green component. - /// The blue component. - /// The alpha component. - public Rgba64(float r, float g, float b, float a) - { - Vector4 clamped = Vector4.Clamp(new Vector4(r, g, b, a), Vector4.Zero, Vector4.One) * 65535f; - this.PackedValue = Pack(ref clamped); - } - - /// - /// Initializes a new instance of the struct. - /// - /// - /// The vector containing the components for the packed vector. - /// - public Rgba64(Vector4 vector) - { - Vector4 clamped = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * 65535f; - this.PackedValue = Pack(ref clamped); - } - - /// - public ulong PackedValue { get; set; } - - /// - /// Compares two objects for equality. - /// - /// - /// The on the left side of the operand. - /// - /// - /// The on the right side of the operand. - /// - /// - /// True if the current left is equal to the parameter; otherwise, false. - /// - public static bool operator ==(Rgba64 left, Rgba64 right) - { - return left.PackedValue == right.PackedValue; - } - - /// - /// Compares two objects for equality. - /// - /// The on the left side of the operand. - /// The on the right side of the operand. - /// - /// True if the current left is equal to the parameter; otherwise, false. - /// - public static bool operator !=(Rgba64 left, Rgba64 right) - { - return left.PackedValue != right.PackedValue; - } - - /// - public void PackVector(Vector4 vector) - { - Vector4 clamped = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * 65535f; - this.PackedValue = Pack(ref clamped); - } - - /// - public void PackBytes(byte x, byte y, byte z, byte w) - { - Vector4 vector = (new Vector4(x, y, z, w) / 255f) * 65535f; - this.PackedValue = Pack(ref vector); - } - - /// - public Vector4 ToVector4() - { - return new Vector4( - (this.PackedValue >> 32) & 0xFFFF, - (this.PackedValue >> 16) & 0xFFFF, - this.PackedValue & 0xFFFF, - (this.PackedValue >> 48) & 0xFFFF) / 65535f; - } - - /// - public byte[] ToBytes() - { - return new[] - { - (byte)((this.PackedValue >> 40) & 255), - (byte)((this.PackedValue >> 24) & 255), - (byte)((this.PackedValue >> 8) & 255), - (byte)((this.PackedValue >> 56) & 255) - }; - } - - /// - public override bool Equals(object obj) - { - return (obj is Rgba64) && this.Equals((Rgba64)obj); - } - - /// - public bool Equals(Rgba64 other) - { - return this.PackedValue == other.PackedValue; - } - - /// - /// Gets a string representation of the packed vector. - /// - /// A string representation of the packed vector. - public override string ToString() - { - return this.ToVector4().ToString(); - } - - /// - public override int GetHashCode() - { - return this.GetHashCode(this); - } - - /// - /// Sets the packed representation from the given component values. - /// - /// - /// The vector containing the components for the packed vector. - /// - /// - /// The . - /// - private static ulong Pack(ref Vector4 vector) - { - return ((ulong)Math.Round(vector.X) << 32) | - ((ulong)Math.Round(vector.Y) << 16) | - (ulong)Math.Round(vector.Z) | - ((ulong)Math.Round(vector.W) << 48); - } - - /// - /// Returns the hash code for this instance. - /// - /// - /// The instance of to return the hash code for. - /// - /// - /// A 32-bit signed integer that is the hash code for this instance. - /// - private int GetHashCode(Rgba64 packed) - { - return packed.PackedValue.GetHashCode(); - } - } -} diff --git a/GenericImage/PixelAccessorRgba32.cs b/GenericImage/PixelAccessorRgba32.cs deleted file mode 100644 index 25b49ea210..0000000000 --- a/GenericImage/PixelAccessorRgba32.cs +++ /dev/null @@ -1,148 +0,0 @@ -namespace GenericImage -{ - using System; - using System.Runtime.InteropServices; - - using GenericImage.PackedVectors; - - /// - /// Provides per-pixel access to an images pixels. - /// - public sealed unsafe class PixelAccessorRgba32 : IPixelAccessor - { - /// - /// The position of the first pixel in the bitmap. - /// - private Rgba32* pixelsBase; - - /// - /// Provides a way to access the pixels from unmanaged memory. - /// - private GCHandle pixelsHandle; - - /// - /// A value indicating whether this instance of the given entity has been disposed. - /// - /// if this instance has been disposed; otherwise, . - /// - /// If the entity is disposed, it must not be disposed a second - /// time. The isDisposed field is set the first time the entity - /// is disposed. If the isDisposed field is true, then the Dispose() - /// method will not dispose again. This help not to prolong the entity's - /// life in the Garbage Collector. - /// - private bool isDisposed; - - /// - /// Initializes a new instance of the class. - /// - /// - /// The image to provide pixel access for. - /// - public PixelAccessorRgba32(ImageBase image) - { - //Guard.NotNull(image, nameof(image)); - //Guard.MustBeGreaterThan(image.Width, 0, "image width"); - //Guard.MustBeGreaterThan(image.Height, 0, "image height"); - - this.Width = image.Width; - this.Height = image.Height; - - this.pixelsHandle = GCHandle.Alloc(image.Pixels, GCHandleType.Pinned); - this.pixelsBase = (Rgba32*)this.pixelsHandle.AddrOfPinnedObject().ToPointer(); - } - - /// - /// Finalizes an instance of the class. - /// - ~PixelAccessorRgba32() - { - this.Dispose(); - } - - /// - /// Gets the width of the image. - /// - public int Width { get; } - - /// - /// Gets the height of the image. - /// - public int Height { get; } - - /// - /// Gets or sets the color of a pixel at the specified position. - /// - /// - /// The x-coordinate of the pixel. Must be greater - /// than zero and smaller than the width of the pixel. - /// - /// - /// The y-coordinate of the pixel. Must be greater - /// than zero and smaller than the width of the pixel. - /// - /// The at the specified position. - public IPackedVector this[int x, int y] - { - get - { -#if DEBUG - if ((x < 0) || (x >= this.Width)) - { - throw new ArgumentOutOfRangeException(nameof(x), "Value cannot be less than zero or greater than the bitmap width."); - } - - if ((y < 0) || (y >= this.Height)) - { - throw new ArgumentOutOfRangeException(nameof(y), "Value cannot be less than zero or greater than the bitmap height."); - } -#endif - return *(this.pixelsBase + ((y * this.Width) + x)); - } - - set - { -#if DEBUG - if ((x < 0) || (x >= this.Width)) - { - throw new ArgumentOutOfRangeException(nameof(x), "Value cannot be less than zero or greater than the bitmap width."); - } - - if ((y < 0) || (y >= this.Height)) - { - throw new ArgumentOutOfRangeException(nameof(y), "Value cannot be less than zero or greater than the bitmap height."); - } -#endif - *(this.pixelsBase + ((y * this.Width) + x)) = (Rgba32)value; - } - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - if (this.isDisposed) - { - return; - } - - if (this.pixelsHandle.IsAllocated) - { - this.pixelsHandle.Free(); - } - - this.pixelsBase = null; - - // Note disposing is done. - this.isDisposed = true; - - // This object will be cleaned up by the Dispose method. - // Therefore, you should call GC.SuppressFinalize to - // take this object off the finalization queue - // and prevent finalization code for this object - // from executing a second time. - GC.SuppressFinalize(this); - } - } -} diff --git a/GenericImage/PixelAccessorRgba64.cs b/GenericImage/PixelAccessorRgba64.cs deleted file mode 100644 index 2dae8a0f16..0000000000 --- a/GenericImage/PixelAccessorRgba64.cs +++ /dev/null @@ -1,148 +0,0 @@ -namespace GenericImage -{ - using System; - using System.Runtime.InteropServices; - - using GenericImage.PackedVectors; - - /// - /// Provides per-pixel access to an images pixels. - /// - public sealed unsafe class PixelAccessorRgba64 : IPixelAccessor - { - /// - /// The position of the first pixel in the bitmap. - /// - private Rgba64* pixelsBase; - - /// - /// Provides a way to access the pixels from unmanaged memory. - /// - private GCHandle pixelsHandle; - - /// - /// A value indicating whether this instance of the given entity has been disposed. - /// - /// if this instance has been disposed; otherwise, . - /// - /// If the entity is disposed, it must not be disposed a second - /// time. The isDisposed field is set the first time the entity - /// is disposed. If the isDisposed field is true, then the Dispose() - /// method will not dispose again. This help not to prolong the entity's - /// life in the Garbage Collector. - /// - private bool isDisposed; - - /// - /// Initializes a new instance of the class. - /// - /// - /// The image to provide pixel access for. - /// - public PixelAccessorRgba64(IImageBase image) - { - //Guard.NotNull(image, nameof(image)); - //Guard.MustBeGreaterThan(image.Width, 0, "image width"); - //Guard.MustBeGreaterThan(image.Height, 0, "image height"); - - this.Width = image.Width; - this.Height = image.Height; - - this.pixelsHandle = GCHandle.Alloc(image.Pixels, GCHandleType.Pinned); - this.pixelsBase = (Rgba64*)this.pixelsHandle.AddrOfPinnedObject().ToPointer(); - } - - /// - /// Finalizes an instance of the class. - /// - ~PixelAccessorRgba64() - { - this.Dispose(); - } - - /// - /// Gets the width of the image. - /// - public int Width { get; } - - /// - /// Gets the height of the image. - /// - public int Height { get; } - - /// - /// Gets or sets the color of a pixel at the specified position. - /// - /// - /// The x-coordinate of the pixel. Must be greater - /// than zero and smaller than the width of the pixel. - /// - /// - /// The y-coordinate of the pixel. Must be greater - /// than zero and smaller than the width of the pixel. - /// - /// The at the specified position. - public IPackedVector this[int x, int y] - { - get - { -#if DEBUG - if ((x < 0) || (x >= this.Width)) - { - throw new ArgumentOutOfRangeException(nameof(x), "Value cannot be less than zero or greater than the bitmap width."); - } - - if ((y < 0) || (y >= this.Height)) - { - throw new ArgumentOutOfRangeException(nameof(y), "Value cannot be less than zero or greater than the bitmap height."); - } -#endif - return *(this.pixelsBase + ((y * this.Width) + x)); - } - - set - { -#if DEBUG - if ((x < 0) || (x >= this.Width)) - { - throw new ArgumentOutOfRangeException(nameof(x), "Value cannot be less than zero or greater than the bitmap width."); - } - - if ((y < 0) || (y >= this.Height)) - { - throw new ArgumentOutOfRangeException(nameof(y), "Value cannot be less than zero or greater than the bitmap height."); - } -#endif - *(this.pixelsBase + ((y * this.Width) + x)) = (Rgba64)value; - } - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - if (this.isDisposed) - { - return; - } - - if (this.pixelsHandle.IsAllocated) - { - this.pixelsHandle.Free(); - } - - this.pixelsBase = null; - - // Note disposing is done. - this.isDisposed = true; - - // This object will be cleaned up by the Dispose method. - // Therefore, you should call GC.SuppressFinalize to - // take this object off the finalization queue - // and prevent finalization code for this object - // from executing a second time. - GC.SuppressFinalize(this); - } - } -} diff --git a/GenericImage/ProgressEventArgs.cs b/GenericImage/ProgressEventArgs.cs deleted file mode 100644 index 5e9a1e9598..0000000000 --- a/GenericImage/ProgressEventArgs.cs +++ /dev/null @@ -1,23 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace GenericImage -{ - /// - /// Contains event data related to the progress made processing an image. - /// - public class ProgressEventArgs : System.EventArgs - { - /// - /// Gets or sets the number of rows processed. - /// - public int RowsProcessed { get; set; } - - /// - /// Gets or sets the total number of rows. - /// - public int TotalRows { get; set; } - } -} \ No newline at end of file diff --git a/GenericImage/Properties/AssemblyInfo.cs b/GenericImage/Properties/AssemblyInfo.cs deleted file mode 100644 index 8dd0359516..0000000000 --- a/GenericImage/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("GenericImage")] -[assembly: AssemblyTrademark("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("45d91211-9d4a-4382-a114-8786859e302a")] diff --git a/GenericImage/ResizeProcessor.cs b/GenericImage/ResizeProcessor.cs deleted file mode 100644 index 9752e2960d..0000000000 --- a/GenericImage/ResizeProcessor.cs +++ /dev/null @@ -1,393 +0,0 @@ -// -// Copyright (c) James Jackson-South and contributors. -// Licensed under the Apache License, Version 2.0. -// - -namespace ImageProcessorCore.Processors -{ - using System; - using System.Numerics; - using System.Threading.Tasks; - - using GenericImage; - - /// - /// Provides methods that allow the resizing of images using various algorithms. - /// - public class ResizeProcessor : ImageProcessor - { - /// - /// Initializes a new instance of the class. - /// - /// - /// The sampler to perform the resize operation. - /// - public ResizeProcessor(IResampler sampler) - { - Guard.NotNull(sampler, nameof(sampler)); - - this.Sampler = sampler; - } - - /// - /// Gets the sampler to perform the resize operation. - /// - public IResampler Sampler { get; } - - /// - /// Gets or sets the horizontal weights. - /// - protected Weights[] HorizontalWeights { get; set; } - - /// - /// Gets or sets the vertical weights. - /// - protected Weights[] VerticalWeights { get; set; } - - /// - protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) - { - if (!(this.Sampler is NearestNeighborResampler)) - { - this.HorizontalWeights = this.PrecomputeWeights(targetRectangle.Width, sourceRectangle.Width); - this.VerticalWeights = this.PrecomputeWeights(targetRectangle.Height, sourceRectangle.Height); - } - } - - /// - protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) - { - // Jump out, we'll deal with that later. - if (source.Bounds == target.Bounds && sourceRectangle == targetRectangle) - { - return; - } - - int width = target.Width; - int height = target.Height; - int sourceHeight = sourceRectangle.Height; - int targetX = target.Bounds.X; - int targetY = target.Bounds.Y; - int targetRight = target.Bounds.Right; - int targetBottom = target.Bounds.Bottom; - int startX = targetRectangle.X; - int endX = targetRectangle.Right; - bool compand = this.Compand; - - if (this.Sampler is NearestNeighborResampler) - { - // Scaling factors - float widthFactor = sourceRectangle.Width / (float)targetRectangle.Width; - float heightFactor = sourceRectangle.Height / (float)targetRectangle.Height; - - using (IPixelAccessor sourcePixels = source.Lock()) - using (IPixelAccessor targetPixels = target.Lock()) - { - Parallel.For( - startY, - endY, - y => - { - if (targetY <= y && y < targetBottom) - { - // Y coordinates of source points - int originY = (int)((y - startY) * heightFactor); - - for (int x = startX; x < endX; x++) - { - if (targetX <= x && x < targetRight) - { - // X coordinates of source points - int originX = (int)((x - startX) * widthFactor); - targetPixels[x, y] = sourcePixels[originX, originY]; - } - } - - this.OnRowProcessed(); - } - }); - } - - // Break out now. - return; - } - - // Interpolate the image using the calculated weights. - // A 2-pass 1D algorithm appears to be faster than splitting a 1-pass 2D algorithm - // First process the columns. Since we are not using multiple threads startY and endY - // are the upper and lower bounds of the source rectangle. - Image firstPass = new Image(target.Width, source.Height); - using (IPixelAccessor sourcePixels = source.Lock()) - using (IPixelAccessor firstPassPixels = firstPass.Lock()) - using (IPixelAccessor targetPixels = target.Lock()) - { - Parallel.For( - 0, - sourceHeight, - y => - { - for (int x = startX; x < endX; x++) - { - if (x >= 0 && x < width) - { - // Ensure offsets are normalised for cropping and padding. - int offsetX = x - startX; - float sum = this.HorizontalWeights[offsetX].Sum; - Weight[] horizontalValues = this.HorizontalWeights[offsetX].Values; - - // Destination color components - //Color destination = new Color(); - - //for (int i = 0; i < sum; i++) - //{ - // Weight xw = horizontalValues[i]; - // int originX = xw.Index; - // Color sourceColor = compand - // ? Color.Expand(sourcePixels[originX, y]) - // : sourcePixels[originX, y]; - - // destination += sourceColor * xw.Value; - //} - - //if (compand) - //{ - // destination = Color.Compress(destination); - //} - - //firstPassPixels[x, y] = destination; - TColor sourceColor; - TColor destination = default(TColor); - - for (int i = 0; i < sum; i++) - { - Weight xw = horizontalValues[i]; - int originX = xw.Index; - sourceColor = sourcePixels[originX, y]; - //Color sourceColor = compand - // ? Color.Expand(sourcePixels[originX, y]) - // : sourcePixels[originX, y]; - //sourceColor.Multiply(xw.Value); - //destination.Add(sourceColor); - //destination += sourceColor * xw.Value; - - sourceColor.Multiply(xw.Value); - destination.Add(sourceColor); - } - - //if (compand) - //{ - // destination = Color.Compress(destination); - //} - //T packed = default(T); - //packed.PackVector(destination); - - firstPassPixels[x, y] = destination; - } - } - }); - - // Now process the rows. - Parallel.For( - startY, - endY, - y => - { - if (y >= 0 && y < height) - { - // Ensure offsets are normalised for cropping and padding. - int offsetY = y - startY; - float sum = this.VerticalWeights[offsetY].Sum; - Weight[] verticalValues = this.VerticalWeights[offsetY].Values; - - for (int x = 0; x < width; x++) - { - // Destination color components - TColor sourceColor; - TColor destination = default(TColor); - - for (int i = 0; i < sum; i++) - { - Weight yw = verticalValues[i]; - int originY = yw.Index; - sourceColor = firstPassPixels[x, originY]; - //Color sourceColor = compand - // ? Color.Expand(firstPassPixels[x, originY]) - // : firstPassPixels[x, originY]; - //Vector4 sourceColor = firstPassPixels[x, originY].ToVector4(); - //destination += sourceColor * yw.Value; - - sourceColor.Multiply(yw.Value); - destination.Add(sourceColor); - } - - //if (compand) - //{ - // destination = Color.Compress(destination); - //} - - //T packed = default(T); - //packed.PackVector(destination); - - targetPixels[x, y] = destination; - } - } - - this.OnRowProcessed(); - }); - - } - } - - /// - protected override void AfterApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) - { - // Copy the pixels over. - if (source.Bounds == target.Bounds && sourceRectangle == targetRectangle) - { - target.ClonePixels(target.Width, target.Height, source.Pixels); - } - } - - /// - /// Computes the weights to apply at each pixel when resizing. - /// - /// The destination section size. - /// The source section size. - /// - /// The . - /// - protected Weights[] PrecomputeWeights(int destinationSize, int sourceSize) - { - float scale = (float)destinationSize / sourceSize; - IResampler sampler = this.Sampler; - float radius = sampler.Radius; - double left; - double right; - float weight; - int index; - int sum; - - Weights[] result = new Weights[destinationSize]; - - // When shrinking, broaden the effective kernel support so that we still - // visit every source pixel. - if (scale < 1) - { - float width = radius / scale; - float filterScale = 1 / scale; - - // Make the weights slices, one source for each column or row. - for (int i = 0; i < destinationSize; i++) - { - float centre = i / scale; - left = Math.Ceiling(centre - width); - right = Math.Floor(centre + width); - - result[i] = new Weights - { - Values = new Weight[(int)(right - left + 1)] - }; - - for (double j = left; j <= right; j++) - { - weight = sampler.GetValue((float)((centre - j) / filterScale)) / filterScale; - if (j < 0) - { - index = (int)-j; - } - else if (j >= sourceSize) - { - index = (int)((sourceSize - j) + sourceSize - 1); - } - else - { - index = (int)j; - } - - sum = (int)result[i].Sum++; - result[i].Values[sum] = new Weight(index, weight); - } - } - } - else - { - // Make the weights slices, one source for each column or row. - for (int i = 0; i < destinationSize; i++) - { - float centre = i / scale; - left = Math.Ceiling(centre - radius); - right = Math.Floor(centre + radius); - result[i] = new Weights - { - Values = new Weight[(int)(right - left + 1)] - }; - - for (double j = left; j <= right; j++) - { - weight = sampler.GetValue((float)(centre - j)); - if (j < 0) - { - index = (int)-j; - } - else if (j >= sourceSize) - { - index = (int)((sourceSize - j) + sourceSize - 1); - } - else - { - index = (int)j; - } - - sum = (int)result[i].Sum++; - result[i].Values[sum] = new Weight(index, weight); - } - } - } - - return result; - } - - /// - /// Represents the weight to be added to a scaled pixel. - /// - protected struct Weight - { - /// - /// Initializes a new instance of the struct. - /// - /// The index. - /// The value. - public Weight(int index, float value) - { - this.Index = index; - this.Value = value; - } - - /// - /// Gets the pixel index. - /// - public int Index { get; } - - /// - /// Gets the result of the interpolation algorithm. - /// - public float Value { get; } - } - - /// - /// Represents a collection of weights and their sum. - /// - protected class Weights - { - /// - /// Gets or sets the values. - /// - public Weight[] Values { get; set; } - - /// - /// Gets or sets the sum. - /// - public float Sum { get; set; } - } - } -} \ No newline at end of file diff --git a/GenericImage/project.json b/GenericImage/project.json deleted file mode 100644 index bdcdc4ff70..0000000000 --- a/GenericImage/project.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "version": "1.0.0-*", - - "buildOptions": { - "allowUnsafe": true, - "debugType": "portable" - }, - "dependencies": { - "System.Collections": "4.0.11", - "System.Diagnostics.Debug": "4.0.11", - "System.Diagnostics.Tools": "4.0.1", - "System.IO": "4.1.0", - "System.IO.Compression": "4.1.0", - "System.Linq": "4.1.0", - "System.Linq.Expressions": "4.1.0", - "System.Numerics.Vectors": "4.1.1", - "System.Resources.ResourceManager": "4.0.1", - "System.Runtime.Extensions": "4.1.0", - "System.Runtime.InteropServices": "4.1.0", - "System.Text.Encoding.Extensions": "4.0.11", - "System.Threading": "4.0.11", - "System.Threading.Tasks": "4.0.11", - "System.Threading.Tasks.Parallel": "4.0.1" - }, - "frameworks": { - "netstandard1.1": { } - } -} diff --git a/ImageProcessorCore.sln b/ImageProcessorCore.sln index 6e8766591b..28b7b107c3 100644 --- a/ImageProcessorCore.sln +++ b/ImageProcessorCore.sln @@ -21,8 +21,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{56801022 EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "ImageProcessorCore.Benchmarks", "tests\ImageProcessorCore.Benchmarks\ImageProcessorCore.Benchmarks.xproj", "{299D8E18-102C-42DE-ADBF-79098EE706A8}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "GenericImage", "GenericImage\GenericImage.xproj", "{45D91211-9D4A-4382-A114-8786859E302A}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -41,10 +39,6 @@ Global {299D8E18-102C-42DE-ADBF-79098EE706A8}.Debug|Any CPU.Build.0 = Debug|Any CPU {299D8E18-102C-42DE-ADBF-79098EE706A8}.Release|Any CPU.ActiveCfg = Release|Any CPU {299D8E18-102C-42DE-ADBF-79098EE706A8}.Release|Any CPU.Build.0 = Release|Any CPU - {45D91211-9D4A-4382-A114-8786859E302A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {45D91211-9D4A-4382-A114-8786859E302A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {45D91211-9D4A-4382-A114-8786859E302A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {45D91211-9D4A-4382-A114-8786859E302A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -53,6 +47,5 @@ Global {2AA31A1F-142C-43F4-8687-09ABCA4B3A26} = {815C0625-CD3D-440F-9F80-2D83856AB7AE} {F836E8E6-B4D9-4208-8346-140C74678B91} = {56801022-D71A-4FBE-BC5B-CBA08E2284EC} {299D8E18-102C-42DE-ADBF-79098EE706A8} = {56801022-D71A-4FBE-BC5B-CBA08E2284EC} - {45D91211-9D4A-4382-A114-8786859E302A} = {815C0625-CD3D-440F-9F80-2D83856AB7AE} EndGlobalSection EndGlobal diff --git a/src/ImageProcessorCore/Bootstrapper.cs b/src/ImageProcessorCore/Bootstrapper.cs index a611119921..98537c46a8 100644 --- a/src/ImageProcessorCore/Bootstrapper.cs +++ b/src/ImageProcessorCore/Bootstrapper.cs @@ -74,7 +74,7 @@ namespace ImageProcessorCore /// The image /// The public IPixelAccessor GetPixelAccessor(IImageBase image) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { Type packed = typeof(T); diff --git a/src/ImageProcessorCore/Common/Helpers/Class.cs b/src/ImageProcessorCore/Common/Helpers/Class.cs deleted file mode 100644 index cf60c9f34a..0000000000 --- a/src/ImageProcessorCore/Common/Helpers/Class.cs +++ /dev/null @@ -1,58 +0,0 @@ -namespace ImageProcessorCore.Helpers -{ - interface INullOp - { - bool HasValue(T value); - bool AddIfNotNull(ref T accumulator, T value); - } - sealed class StructNullOp - : INullOp, INullOp - where T : struct - { - public bool HasValue(T value) - { - return true; - } - public bool AddIfNotNull(ref T accumulator, T value) - { - accumulator = Operator.Add(accumulator, value); - return true; - } - public bool HasValue(T? value) - { - return value.HasValue; - } - public bool AddIfNotNull(ref T? accumulator, T? value) - { - if (value.HasValue) - { - accumulator = accumulator.HasValue ? - Operator.Add( - accumulator.GetValueOrDefault(), - value.GetValueOrDefault()) - : value; - return true; - } - return false; - } - } - sealed class ClassNullOp - : INullOp - where T : class - { - public bool HasValue(T value) - { - return value != null; - } - public bool AddIfNotNull(ref T accumulator, T value) - { - if (value != null) - { - accumulator = accumulator == null ? - value : Operator.Add(accumulator, value); - return true; - } - return false; - } - } -} diff --git a/src/ImageProcessorCore/Common/Helpers/ExpressionUtil.cs b/src/ImageProcessorCore/Common/Helpers/ExpressionUtil.cs deleted file mode 100644 index b3c7dbe80e..0000000000 --- a/src/ImageProcessorCore/Common/Helpers/ExpressionUtil.cs +++ /dev/null @@ -1,100 +0,0 @@ -namespace ImageProcessorCore.Helpers -{ - using System; - using System.Linq.Expressions; - - /// - /// General purpose Expression utilities - /// - public static class ExpressionUtil - { - /// - /// Create a function delegate representing a unary operation - /// - /// The parameter type - /// The return type - /// Body factory - /// Compiled function delegate - public static Func CreateExpression( - Func body) - { - ParameterExpression inp = Expression.Parameter(typeof(TArg1), "inp"); - try - { - return Expression.Lambda>(body(inp), inp).Compile(); - } - catch (Exception ex) - { - string msg = ex.Message; // avoid capture of ex itself - return delegate { throw new InvalidOperationException(msg); }; - } - } - - /// - /// Create a function delegate representing a binary operation - /// - /// The first parameter type - /// The second parameter type - /// The return type - /// Body factory - /// Compiled function delegate - public static Func CreateExpression( - Func body) - { - return CreateExpression(body, false); - } - - /// - /// Create a function delegate representing a binary operation - /// - /// - /// If no matching operation is possible, attempt to convert - /// TArg1 and TArg2 to TResult for a match? For example, there is no - /// "decimal operator /(decimal, int)", but by converting TArg2 (int) to - /// TResult (decimal) a match is found. - /// - /// The first parameter type - /// The second parameter type - /// The return type - /// Body factory - /// Compiled function delegate - public static Func CreateExpression( - Func body, bool castArgsToResultOnFailure) - { - ParameterExpression lhs = Expression.Parameter(typeof(TArg1), "lhs"); - ParameterExpression rhs = Expression.Parameter(typeof(TArg2), "rhs"); - try - { - try - { - return Expression.Lambda>(body(lhs, rhs), lhs, rhs).Compile(); - } - catch (InvalidOperationException) - { - // If we show retry and the args aren't already "TValue, TValue, TValue"... - // convert both lhs and rhs to TResult (as appropriate) - if (castArgsToResultOnFailure && !(typeof(TArg1) == typeof(TResult) && typeof(TArg2) == typeof(TResult))) - { - Expression castLhs = typeof(TArg1) == typeof(TResult) - ? lhs - : (Expression)Expression.Convert(lhs, typeof(TResult)); - - Expression castRhs = typeof(TArg2) == typeof(TResult) - ? rhs - : (Expression)Expression.Convert(rhs, typeof(TResult)); - - return Expression.Lambda>( - body(castLhs, castRhs), lhs, rhs).Compile(); - } - - throw; - } - } - catch (Exception ex) - { - string msg = ex.Message; // avoid capture of ex itself - return delegate { throw new InvalidOperationException(msg); }; - } - } - } -} diff --git a/src/ImageProcessorCore/Common/Helpers/Operator.cs b/src/ImageProcessorCore/Common/Helpers/Operator.cs deleted file mode 100644 index 8d0d03caae..0000000000 --- a/src/ImageProcessorCore/Common/Helpers/Operator.cs +++ /dev/null @@ -1,479 +0,0 @@ -namespace ImageProcessorCore.Helpers -{ - using System; - using System.Linq.Expressions; - using System.Reflection; - - /// - /// The Operator class provides easy access to the standard operators - /// (addition, etc) for generic types, using type inference to simplify - /// usage. - /// - public static class Operator - { - - /// - /// Indicates if the supplied value is non-null, - /// for reference-types or Nullable<T> - /// - /// True for non-null values, else false - public static bool HasValue(T value) - { - - return Operator.NullOp.HasValue(value); - - } - - /// - /// Increments the accumulator only - /// if the value is non-null. If the accumulator - /// is null, then the accumulator is given the new - /// value; otherwise the accumulator and value - /// are added. - /// - /// The current total to be incremented (can be null) - /// The value to be tested and added to the accumulator - /// True if the value is non-null, else false - i.e. - /// "has the accumulator been updated?" - public static bool AddIfNotNull(ref T accumulator, T value) - { - return Operator.NullOp.AddIfNotNull(ref accumulator, value); - } - - /// - /// Evaluates unary negation (-) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T Negate(T value) - { - return Operator.Negate(value); - } - /// - /// Evaluates bitwise not (~) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T Not(T value) - { - return Operator.Not(value); - } - /// - /// Evaluates bitwise or (|) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T Or(T value1, T value2) - { - return Operator.Or(value1, value2); - } - /// - /// Evaluates bitwise and (&) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T And(T value1, T value2) - { - return Operator.And(value1, value2); - } - /// - /// Evaluates bitwise xor (^) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T Xor(T value1, T value2) - { - return Operator.Xor(value1, value2); - } - /// - /// Performs a conversion between the given types; this will throw - /// an InvalidOperationException if the type T does not provide a suitable cast, or for - /// Nullable<TInner> if TInner does not provide this cast. - /// - public static TTo Convert(TFrom value) - { - return Operator.Convert(value); - } - /// - /// Evaluates binary addition (+) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T Add(T value1, T value2) - { - return Operator.Add(value1, value2); - } - /// - /// Evaluates binary addition (+) for the given type(s); this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static TArg1 AddAlternative(TArg1 value1, TArg2 value2) - { - return Operator.Add(value1, value2); - } - /// - /// Evaluates binary subtraction (-) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T Subtract(T value1, T value2) - { - return Operator.Subtract(value1, value2); - } - /// - /// Evaluates binary subtraction(-) for the given type(s); this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static TArg1 SubtractAlternative(TArg1 value1, TArg2 value2) - { - return Operator.Subtract(value1, value2); - } - /// - /// Evaluates binary multiplication (*) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T Multiply(T value1, T value2) - { - return Operator.Multiply(value1, value2); - } - /// - /// Evaluates binary multiplication (*) for the given type(s); this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static TArg1 MultiplyAlternative(TArg1 value1, TArg2 value2) - { - return Operator.Multiply(value1, value2); - } - /// - /// Evaluates binary division (/) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static T Divide(T value1, T value2) - { - return Operator.Divide(value1, value2); - } - /// - /// Evaluates binary division (/) for the given type(s); this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static TArg1 DivideAlternative(TArg1 value1, TArg2 value2) - { - return Operator.Divide(value1, value2); - } - /// - /// Evaluates binary equality (==) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static bool Equal(T value1, T value2) - { - return Operator.Equal(value1, value2); - } - /// - /// Evaluates binary inequality (!=) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static bool NotEqual(T value1, T value2) - { - return Operator.NotEqual(value1, value2); - } - /// - /// Evaluates binary greater-than (>) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static bool GreaterThan(T value1, T value2) - { - return Operator.GreaterThan(value1, value2); - } - /// - /// Evaluates binary less-than (<) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static bool LessThan(T value1, T value2) - { - return Operator.LessThan(value1, value2); - } - /// - /// Evaluates binary greater-than-on-eqauls (>=) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static bool GreaterThanOrEqual(T value1, T value2) - { - return Operator.GreaterThanOrEqual(value1, value2); - } - /// - /// Evaluates binary less-than-or-equal (<=) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static bool LessThanOrEqual(T value1, T value2) - { - return Operator.LessThanOrEqual(value1, value2); - } - /// - /// Evaluates integer division (/) for the given type; this will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - /// This operation is particularly useful for computing averages and - /// similar aggregates. - /// - public static T DivideInt32(T value, int divisor) - { - return Operator.Divide(value, divisor); - } - } - /// - /// Provides standard operators (such as addition) that operate over operands of - /// different types. For operators, the return type is assumed to match the first - /// operand. - /// - /// - /// - public static class Operator - { - private static readonly Func convert; - /// - /// Returns a delegate to convert a value between two types; this delegate will throw - /// an InvalidOperationException if the type T does not provide a suitable cast, or for - /// Nullable<TInner> if TInner does not provide this cast. - /// - public static Func Convert => convert; - - static Operator() - { - convert = ExpressionUtil.CreateExpression(body => Expression.Convert(body, typeof(TResult))); - add = ExpressionUtil.CreateExpression(Expression.Add, true); - subtract = ExpressionUtil.CreateExpression(Expression.Subtract, true); - multiply = ExpressionUtil.CreateExpression(Expression.Multiply, true); - divide = ExpressionUtil.CreateExpression(Expression.Divide, true); - } - - private static readonly Func add, subtract, multiply, divide; - - private static readonly Func multiplyF, divideF; - - /// - /// Returns a delegate to evaluate binary addition (+) for the given types; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Add => add; - - /// - /// Returns a delegate to evaluate binary subtraction (-) for the given types; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Subtract => subtract; - - /// - /// Returns a delegate to evaluate binary multiplication (*) for the given types; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Multiply => multiply; - - /// - /// Returns a delegate to evaluate binary division (/) for the given types; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Divide => divide; - - public static Func MultiplyF => multiplyF; - - public static Func DivideF => divideF; - } - - /// - /// Provides standard operators (such as addition) over a single type - /// - /// - /// - public static class Operator - { - static readonly INullOp nullOp; - internal static INullOp NullOp => nullOp; - - static readonly T zero; - /// - /// Returns the zero value for value-types (even full Nullable<TInner>) - or null for reference types - /// - public static T Zero => zero; - - static readonly Func negate, not; - static readonly Func or, and, xor; - /// - /// Returns a delegate to evaluate unary negation (-) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Negate => negate; - - /// - /// Returns a delegate to evaluate bitwise not (~) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Not => not; - - /// - /// Returns a delegate to evaluate bitwise or (|) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Or => or; - - /// - /// Returns a delegate to evaluate bitwise and (&) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func And => and; - - /// - /// Returns a delegate to evaluate bitwise xor (^) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Xor => xor; - - static readonly Func add, subtract, multiply, divide; - - static readonly Func multiplyF, divideF; - - /// - /// Returns a delegate to evaluate binary addition (+) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Add => add; - - /// - /// Returns a delegate to evaluate binary subtraction (-) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Subtract => subtract; - - /// - /// Returns a delegate to evaluate binary multiplication (*) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Multiply => multiply; - - /// - /// Returns a delegate to evaluate binary division (/) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Divide => divide; - - public static Func MultiplyF => multiplyF; - - public static Func DivideF => divideF; - - static readonly Func equal, notEqual, greaterThan, lessThan, greaterThanOrEqual, lessThanOrEqual; - - /// - /// Returns a delegate to evaluate binary equality (==) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func Equal => equal; - - /// - /// Returns a delegate to evaluate binary inequality (!=) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func NotEqual => notEqual; - - /// - /// Returns a delegate to evaluate binary greater-then (>) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func GreaterThan => greaterThan; - - /// - /// Returns a delegate to evaluate binary less-than (<) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func LessThan => lessThan; - - /// - /// Returns a delegate to evaluate binary greater-than-or-equal (>=) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func GreaterThanOrEqual => greaterThanOrEqual; - - /// - /// Returns a delegate to evaluate binary less-than-or-equal (<=) for the given type; this delegate will throw - /// an InvalidOperationException if the type T does not provide this operator, or for - /// Nullable<TInner> if TInner does not provide this operator. - /// - public static Func LessThanOrEqual => lessThanOrEqual; - - static Operator() - { - add = ExpressionUtil.CreateExpression(Expression.Add); - subtract = ExpressionUtil.CreateExpression(Expression.Subtract); - divide = ExpressionUtil.CreateExpression(Expression.Divide); - multiply = ExpressionUtil.CreateExpression(Expression.Multiply); - multiplyF = ExpressionUtil.CreateExpression(Expression.Multiply); - divideF = ExpressionUtil.CreateExpression(Expression.Multiply); - - greaterThan = ExpressionUtil.CreateExpression(Expression.GreaterThan); - greaterThanOrEqual = ExpressionUtil.CreateExpression(Expression.GreaterThanOrEqual); - lessThan = ExpressionUtil.CreateExpression(Expression.LessThan); - lessThanOrEqual = ExpressionUtil.CreateExpression(Expression.LessThanOrEqual); - equal = ExpressionUtil.CreateExpression(Expression.Equal); - notEqual = ExpressionUtil.CreateExpression(Expression.NotEqual); - - negate = ExpressionUtil.CreateExpression(Expression.Negate); - and = ExpressionUtil.CreateExpression(Expression.And); - or = ExpressionUtil.CreateExpression(Expression.Or); - not = ExpressionUtil.CreateExpression(Expression.Not); - xor = ExpressionUtil.CreateExpression(Expression.ExclusiveOr); - - Type typeT = typeof(T); - if (typeT.GetTypeInfo().IsValueType && typeT.GetTypeInfo().IsGenericType && (typeT.GetGenericTypeDefinition() == typeof(Nullable<>))) - { - // get the *inner* zero (not a null Nullable, but default(TValue)) - Type nullType = typeT.GetTypeInfo().GenericTypeArguments[0]; - zero = (T)Activator.CreateInstance(nullType); - nullOp = (INullOp)Activator.CreateInstance( - typeof(StructNullOp<>).MakeGenericType(nullType)); - } - else - { - zero = default(T); - if (typeT.GetTypeInfo().IsValueType) - { - nullOp = (INullOp)Activator.CreateInstance( - typeof(StructNullOp<>).MakeGenericType(typeT)); - } - else - { - nullOp = (INullOp)Activator.CreateInstance( - typeof(ClassNullOp<>).MakeGenericType(typeT)); - } - } - } - } -} diff --git a/src/ImageProcessorCore/Formats/Bmp/BmpDecoder.cs b/src/ImageProcessorCore/Formats/Bmp/BmpDecoder.cs index 916bddce7b..f55fa28edd 100644 --- a/src/ImageProcessorCore/Formats/Bmp/BmpDecoder.cs +++ b/src/ImageProcessorCore/Formats/Bmp/BmpDecoder.cs @@ -75,7 +75,7 @@ namespace ImageProcessorCore.Formats /// The to decode to. /// The containing image data. public void Decode(Image image, Stream stream) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { new BmpDecoderCore().Decode(image, stream); diff --git a/src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs b/src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs index faa0113697..391654f219 100644 --- a/src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs @@ -60,7 +60,7 @@ namespace ImageProcessorCore.Formats /// is null. /// public void Decode(Image image, Stream stream) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { this.currentStream = stream; @@ -195,7 +195,7 @@ namespace ImageProcessorCore.Formats /// The number of bits per pixel. /// Whether the bitmap is inverted. private void ReadRgbPalette(T[] imageData, byte[] colors, int width, int height, int bits, bool inverted) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { // Pixels per byte (bits per pixel) @@ -256,7 +256,7 @@ namespace ImageProcessorCore.Formats /// The height of the bitmap. /// Whether the bitmap is inverted. private void ReadRgb16(T[] imageData, int width, int height, bool inverted) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { // We divide here as we will store the colors in our floating point format. @@ -305,7 +305,7 @@ namespace ImageProcessorCore.Formats /// The height of the bitmap. /// Whether the bitmap is inverted. private void ReadRgb24(T[] imageData, int width, int height, bool inverted) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { int alignment; @@ -344,7 +344,7 @@ namespace ImageProcessorCore.Formats /// The height of the bitmap. /// Whether the bitmap is inverted. private void ReadRgb32(T[] imageData, int width, int height, bool inverted) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { int alignment; diff --git a/src/ImageProcessorCore/Formats/Bmp/BmpEncoder.cs b/src/ImageProcessorCore/Formats/Bmp/BmpEncoder.cs index 07ada9c05a..b7fbdd12ac 100644 --- a/src/ImageProcessorCore/Formats/Bmp/BmpEncoder.cs +++ b/src/ImageProcessorCore/Formats/Bmp/BmpEncoder.cs @@ -44,7 +44,7 @@ namespace ImageProcessorCore.Formats /// public void Encode(ImageBase image, Stream stream) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { BmpEncoderCore encoder = new BmpEncoderCore(); diff --git a/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs b/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs index cc26ea700c..de67b9fe43 100644 --- a/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs +++ b/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs @@ -29,7 +29,7 @@ namespace ImageProcessorCore.Formats /// The to encode the image data to. /// The public void Encode(ImageBase image, Stream stream, BmpBitsPerPixel bitsPerPixel) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { Guard.NotNull(image, nameof(image)); @@ -129,7 +129,7 @@ namespace ImageProcessorCore.Formats /// The containing pixel data. /// private void WriteImage(EndianBinaryWriter writer, ImageBase image) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { // TODO: Add more compression formats. @@ -162,7 +162,7 @@ namespace ImageProcessorCore.Formats /// The containing pixel data. /// The amount to pad each row by. private void Write32bit(EndianBinaryWriter writer, IPixelAccessor pixels, int amount) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { for (int y = pixels.Height - 1; y >= 0; y--) @@ -189,7 +189,7 @@ namespace ImageProcessorCore.Formats /// The containing pixel data. /// The amount to pad each row by. private void Write24bit(EndianBinaryWriter writer, IPixelAccessor pixels, int amount) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { for (int y = pixels.Height - 1; y >= 0; y--) diff --git a/src/ImageProcessorCore/Formats/IImageDecoder.cs b/src/ImageProcessorCore/Formats/IImageDecoder.cs index 09dbcdb1e7..e2e89f2df4 100644 --- a/src/ImageProcessorCore/Formats/IImageDecoder.cs +++ b/src/ImageProcessorCore/Formats/IImageDecoder.cs @@ -45,7 +45,7 @@ namespace ImageProcessorCore.Formats /// The to decode to. /// The containing image data. void Decode(Image image, Stream stream) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct; } } diff --git a/src/ImageProcessorCore/Formats/IImageEncoder.cs b/src/ImageProcessorCore/Formats/IImageEncoder.cs index 7738968631..f040619e55 100644 --- a/src/ImageProcessorCore/Formats/IImageEncoder.cs +++ b/src/ImageProcessorCore/Formats/IImageEncoder.cs @@ -49,7 +49,7 @@ namespace ImageProcessorCore.Formats /// The to encode from. /// The to encode the image data to. void Encode(ImageBase image, Stream stream) - where T : IPackedVector, + where T : IPackedVector, new() where TP : struct; } } diff --git a/src/ImageProcessorCore/Image/IImageBase.cs b/src/ImageProcessorCore/Image/IImageBase.cs index 256a238f3b..db78d127b9 100644 --- a/src/ImageProcessorCore/Image/IImageBase.cs +++ b/src/ImageProcessorCore/Image/IImageBase.cs @@ -3,7 +3,7 @@ namespace ImageProcessorCore { public interface IImageBase : IImageBase - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { T[] Pixels { get; } diff --git a/src/ImageProcessorCore/Image/IImageFrame.cs b/src/ImageProcessorCore/Image/IImageFrame.cs index 744716fafe..dadc5dd1c6 100644 --- a/src/ImageProcessorCore/Image/IImageFrame.cs +++ b/src/ImageProcessorCore/Image/IImageFrame.cs @@ -1,7 +1,7 @@ namespace ImageProcessorCore { public interface IImageFrame : IImageBase - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { } diff --git a/src/ImageProcessorCore/Image/IImageProcessor.cs b/src/ImageProcessorCore/Image/IImageProcessor.cs index 6e92c7c8cf..617dc76cdc 100644 --- a/src/ImageProcessorCore/Image/IImageProcessor.cs +++ b/src/ImageProcessorCore/Image/IImageProcessor.cs @@ -46,7 +46,7 @@ namespace ImageProcessorCore.Processors /// doesnt fit the dimension of the image. /// void Apply(ImageBase target, ImageBase source, Rectangle sourceRectangle) - where T : IPackedVector, + where T : IPackedVector, new() where TP : struct; /// @@ -70,7 +70,7 @@ namespace ImageProcessorCore.Processors /// the result of image process as new image. /// void Apply(ImageBase target, ImageBase source, int width, int height, Rectangle targetRectangle, Rectangle sourceRectangle) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct; } } diff --git a/src/ImageProcessorCore/Image/Image.cs b/src/ImageProcessorCore/Image/Image.cs index 890feb9f89..67d0b53e40 100644 --- a/src/ImageProcessorCore/Image/Image.cs +++ b/src/ImageProcessorCore/Image/Image.cs @@ -21,7 +21,7 @@ namespace ImageProcessorCore /// The packed vector containing pixel information. /// public class Image : ImageBase - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { /// diff --git a/src/ImageProcessorCore/Image/ImageBase.cs b/src/ImageProcessorCore/Image/ImageBase.cs index ec455f271d..691f7450dd 100644 --- a/src/ImageProcessorCore/Image/ImageBase.cs +++ b/src/ImageProcessorCore/Image/ImageBase.cs @@ -15,7 +15,7 @@ namespace ImageProcessorCore /// The packed vector pixels format. /// public abstract class ImageBase : IImageBase - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { /// diff --git a/src/ImageProcessorCore/Image/ImageExtensions.cs b/src/ImageProcessorCore/Image/ImageExtensions.cs index c38f951a8d..b65bdc760a 100644 --- a/src/ImageProcessorCore/Image/ImageExtensions.cs +++ b/src/ImageProcessorCore/Image/ImageExtensions.cs @@ -62,7 +62,7 @@ namespace ImageProcessorCore /// The processor to apply to the image. /// The . public static Image Process(this Image source, IImageProcessor processor) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { return Process(source, source.Bounds, processor); @@ -80,7 +80,7 @@ namespace ImageProcessorCore /// The processors to apply to the image. /// The . public static Image Process(this Image source, Rectangle sourceRectangle, IImageProcessor processor) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { return PerformAction(source, true, (sourceImage, targetImage) => processor.Apply(targetImage, sourceImage, sourceRectangle)); @@ -99,7 +99,7 @@ namespace ImageProcessorCore /// The processor to apply to the image. /// The . public static Image Process(this Image source, int width, int height, IImageSampler sampler) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { return Process(source, width, height, source.Bounds, default(Rectangle), sampler); @@ -125,7 +125,7 @@ namespace ImageProcessorCore /// The processor to apply to the image. /// The . public static Image Process(this Image source, int width, int height, Rectangle sourceRectangle, Rectangle targetRectangle, IImageSampler sampler) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { return PerformAction(source, false, (sourceImage, targetImage) => sampler.Apply(targetImage, sourceImage, width, height, targetRectangle, sourceRectangle)); @@ -140,7 +140,7 @@ namespace ImageProcessorCore /// The to perform against the image. /// The . private static Image PerformAction(Image source, bool clone, Action, ImageBase> action) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { Image transformedImage = clone diff --git a/src/ImageProcessorCore/Image/ImageFrame.cs b/src/ImageProcessorCore/Image/ImageFrame.cs index 0846dc7783..84ea69fa09 100644 --- a/src/ImageProcessorCore/Image/ImageFrame.cs +++ b/src/ImageProcessorCore/Image/ImageFrame.cs @@ -12,7 +12,7 @@ namespace ImageProcessorCore /// The packed vector containing pixel information. /// public class ImageFrame : ImageBase - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { /// diff --git a/src/ImageProcessorCore/ImageProcessor.cs b/src/ImageProcessorCore/ImageProcessor.cs index bfa8eacdfc..7569435c0b 100644 --- a/src/ImageProcessorCore/ImageProcessor.cs +++ b/src/ImageProcessorCore/ImageProcessor.cs @@ -28,7 +28,7 @@ namespace ImageProcessorCore.Processors /// public void Apply(ImageBase target, ImageBase source, Rectangle sourceRectangle) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { try @@ -51,7 +51,7 @@ namespace ImageProcessorCore.Processors /// public void Apply(ImageBase target, ImageBase source, int width, int height, Rectangle targetRectangle = default(Rectangle), Rectangle sourceRectangle = default(Rectangle)) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { try @@ -98,7 +98,7 @@ namespace ImageProcessorCore.Processors /// The structure that specifies the portion of the image object to draw. /// protected virtual void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { } @@ -124,7 +124,7 @@ namespace ImageProcessorCore.Processors /// the result of image process as new image. /// protected abstract void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct; /// @@ -141,7 +141,7 @@ namespace ImageProcessorCore.Processors /// The structure that specifies the portion of the image object to draw. /// protected virtual void AfterApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { } diff --git a/src/ImageProcessorCore/PackedVector/Bgra32.cs b/src/ImageProcessorCore/PackedVector/Bgra32.cs index 9c1848aab4..7020d43b76 100644 --- a/src/ImageProcessorCore/PackedVector/Bgra32.cs +++ b/src/ImageProcessorCore/PackedVector/Bgra32.cs @@ -2,6 +2,7 @@ // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // + namespace ImageProcessorCore { using System; @@ -10,17 +11,11 @@ namespace ImageProcessorCore /// /// Packed vector type containing four 8-bit unsigned normalized values ranging from 0 to 1. /// - public unsafe struct Bgra32 : IPackedVector, IEquatable + public struct Bgra32 : IPackedVector, IEquatable { - const uint B_MASK = 0x000000FF; - const uint G_MASK = 0x0000FF00; - const uint R_MASK = 0x00FF0000; - const uint A_MASK = 0xFF000000; - const int B_SHIFT = 0; - const int G_SHIFT = 8; - const int R_SHIFT = 16; - const int A_SHIFT = 24; - + /// + /// The packed value. + /// private uint packedValue; /// @@ -31,11 +26,29 @@ namespace ImageProcessorCore /// The red component. /// The alpha component. public Bgra32(float b, float g, float r, float a) + : this() { Vector4 clamped = Vector4.Clamp(new Vector4(b, g, r, a), Vector4.Zero, Vector4.One) * 255f; this.packedValue = Pack(ref clamped); } + /// + /// Initializes a new instance of the struct. + /// + /// The blue component. + /// The green component. + /// The red component. + /// The alpha component. + public Bgra32(byte b, byte g, byte r, byte a) + : this() + { + this.B = b; + this.G = g; + this.R = r; + this.A = a; + this.packedValue = this.Pack(); + } + /// /// Initializes a new instance of the struct. /// @@ -43,194 +56,31 @@ namespace ImageProcessorCore /// The vector containing the components for the packed vector. /// public Bgra32(Vector4 vector) + : this() { Vector4 clamped = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * 255f; this.packedValue = Pack(ref clamped); } - public byte B - { - get - { - return (byte)(this.packedValue & B_MASK); - } - - set - { - this.packedValue = (this.packedValue & ~B_MASK) | value; - } - } - - public byte G - { - get - { - return (byte)((this.packedValue & G_MASK) >> G_SHIFT); - } - - set - { - this.packedValue = (this.packedValue & ~G_MASK) | (((uint)value) << G_SHIFT); - } - } - - public byte R - { - get - { - return (byte)((this.packedValue & R_MASK) >> R_SHIFT); - } - - set - { - this.packedValue = (this.packedValue & ~R_MASK) | (((uint)value) << R_SHIFT); - } - } - - public byte A - { - get - { - return (byte)((this.packedValue & A_MASK) >> A_SHIFT); - } - - set - { - this.packedValue = (this.packedValue & ~A_MASK) | (((uint)value) << A_SHIFT); - } - } - - /// - public uint PackedValue() - { - return this.packedValue; - } - - public void Add(TP value) where TP : IPackedVector - { - // this.PackVector(this.ToVector4() + value.ToVector4()); - } - - public void Subtract(TP value) where TP : IPackedVector - { - // this.PackVector(this.ToVector4() - value.ToVector4()); - } - - public void Multiply(TP value) where TP : IPackedVector - { - // this.PackVector(this.ToVector4() * value.ToVector4()); - } - - public void Multiply(float value) where TP : IPackedVector - { - this.B = (byte)(this.B * value); - this.G = (byte)(this.G * value); - this.R = (byte)(this.R * value); - this.A = (byte)(this.A * value); - } - - public void Divide(TP value) where TP : IPackedVector - { - // this.PackVector(this.ToVector4() / value.ToVector4()); - } - - public void Divide(float value) where TP : IPackedVector - { - this.B = (byte)(this.B / value); - this.G = (byte)(this.G / value); - this.R = (byte)(this.R / value); - this.A = (byte)(this.A / value); - } - /// - /// Computes the product of multiplying a Bgra32 by a given factor. + /// Gets or sets the blue component. /// - /// The Bgra32. - /// The multiplication factor. - /// - /// The - /// - public static Bgra32 operator *(Bgra32 value, float factor) - { - byte b = (byte)(value.B * factor); - byte g = (byte)(value.G * factor); - byte r = (byte)(value.R * factor); - byte a = (byte)(value.A * factor); - - return new Bgra32(b, g, r, a); - } + public byte B { get; set; } /// - /// Computes the product of multiplying a Bgra32 by a given factor. + /// Gets or sets the green component. /// - /// The multiplication factor. - /// The Bgra32. - /// - /// The - /// - public static Bgra32 operator *(float factor, Bgra32 value) - { - byte b = (byte)(value.B * factor); - byte g = (byte)(value.G * factor); - byte r = (byte)(value.R * factor); - byte a = (byte)(value.A * factor); - - return new Bgra32(b, g, r, a); - } - - /// - /// Computes the product of multiplying two Bgra32s. - /// - /// The Bgra32 on the left hand of the operand. - /// The Bgra32 on the right hand of the operand. - /// - /// The - /// - public static Bgra32 operator *(Bgra32 left, Bgra32 right) - { - byte b = (byte)(left.B * right.B); - byte g = (byte)(left.G * right.G); - byte r = (byte)(left.R * right.R); - byte a = (byte)(left.A * right.A); - - return new Bgra32(b, g, r, a); - } + public byte G { get; set; } /// - /// Computes the sum of adding two Bgra32s. + /// Gets or sets the red component. /// - /// The Bgra32 on the left hand of the operand. - /// The Bgra32 on the right hand of the operand. - /// - /// The - /// - public static Bgra32 operator +(Bgra32 left, Bgra32 right) - { - byte b = (byte)(left.B + right.B); - byte g = (byte)(left.G + right.G); - byte r = (byte)(left.R + right.R); - byte a = (byte)(left.A + right.A); - - return new Bgra32(b, g, r, a); - } + public byte R { get; set; } /// - /// Computes the difference left by subtracting one Bgra32 from another. + /// Gets or sets the alpha component. /// - /// The Bgra32 on the left hand of the operand. - /// The Bgra32 on the right hand of the operand. - /// - /// The - /// - public static Bgra32 operator -(Bgra32 left, Bgra32 right) - { - byte b = (byte)(left.B - right.B); - byte g = (byte)(left.G - right.G); - byte r = (byte)(left.R - right.R); - byte a = (byte)(left.A - right.A); - - return new Bgra32(b, g, r, a); - } + public byte A { get; set; } /// /// Compares two objects for equality. @@ -262,6 +112,61 @@ namespace ImageProcessorCore return left.packedValue != right.packedValue; } + /// + public uint PackedValue() + { + this.packedValue = this.Pack(); + return this.packedValue; + } + + public void Add(Bgra32 value) + { + this.B = (byte)(this.B + value.B); + this.G = (byte)(this.G + value.G); + this.R = (byte)(this.R + value.R); + this.A = (byte)(this.A + value.A); + } + + public void Subtract(Bgra32 value) + { + this.B = (byte)(this.B - value.B); + this.G = (byte)(this.G - value.G); + this.R = (byte)(this.R - value.R); + this.A = (byte)(this.A - value.A); + } + + public void Multiply(Bgra32 value) + { + this.B = (byte)(this.B * value.B); + this.G = (byte)(this.G * value.G); + this.R = (byte)(this.R * value.R); + this.A = (byte)(this.A * value.A); + } + + public void Multiply(float value) + { + this.B = (byte)(this.B * value); + this.G = (byte)(this.G * value); + this.R = (byte)(this.R * value); + this.A = (byte)(this.A * value); + } + + public void Divide(Bgra32 value) + { + this.B = (byte)(this.B / value.B); + this.G = (byte)(this.G / value.G); + this.R = (byte)(this.R / value.R); + this.A = (byte)(this.A / value.A); + } + + public void Divide(float value) + { + this.B = (byte)(this.B / value); + this.G = (byte)(this.G / value); + this.R = (byte)(this.R / value); + this.A = (byte)(this.A / value); + } + /// public void PackVector(Vector4 vector) { @@ -272,7 +177,11 @@ namespace ImageProcessorCore /// public void PackBytes(byte x, byte y, byte z, byte w) { - this.packedValue = Pack(ref x, ref y, ref z, ref w); + this.B = x; + this.G = y; + this.R = z; + this.A = w; + this.packedValue = this.Pack(); } /// @@ -341,9 +250,15 @@ namespace ImageProcessorCore ((uint)Math.Round(vector.W) << 24); } - private static uint Pack(ref byte x, ref byte y, ref byte z, ref byte w) + /// + /// Sets the packed representation from the given component values. + /// + /// + /// The . + /// + private uint Pack() { - return x | ((uint)y << 8) | ((uint)z << 16) | ((uint)w << 24); + return this.B | ((uint)this.G << 8) | ((uint)this.R << 16) | ((uint)this.A << 24); } /// diff --git a/src/ImageProcessorCore/PackedVector/IPackedVector.cs b/src/ImageProcessorCore/PackedVector/IPackedVector.cs index 2beeb2c809..5f8a369a4a 100644 --- a/src/ImageProcessorCore/PackedVector/IPackedVector.cs +++ b/src/ImageProcessorCore/PackedVector/IPackedVector.cs @@ -14,26 +14,26 @@ namespace ImageProcessorCore /// /// The type of object representing the packed value. /// - public interface IPackedVector : IPackedVector - where T : struct + public interface IPackedVector : IPackedVector + where TP : struct { /// /// Gets the packed representation of the value. /// Typically packed in least to greatest significance order. /// - T PackedValue(); + TP PackedValue(); - void Add(TP value) where TP : IPackedVector; + void Add(T value); - void Subtract(TP value) where TP : IPackedVector; + void Subtract(T value); - void Multiply(TP value) where TP : IPackedVector; + void Multiply(T value); - void Multiply(float value) where TP : IPackedVector; + void Multiply(float value); - void Divide(TP value) where TP : IPackedVector; + void Divide(T value); - void Divide(float value) where TP : IPackedVector; + void Divide(float value); } /// diff --git a/src/ImageProcessorCore/PixelAccessor/IPixelAccessor.cs b/src/ImageProcessorCore/PixelAccessor/IPixelAccessor.cs index e41e7d0d9b..20830e4a8f 100644 --- a/src/ImageProcessorCore/PixelAccessor/IPixelAccessor.cs +++ b/src/ImageProcessorCore/PixelAccessor/IPixelAccessor.cs @@ -11,7 +11,7 @@ namespace ImageProcessorCore /// Encapsulates properties to provides per-pixel access to an images pixels. /// public interface IPixelAccessor : IPixelAccessor - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { /// diff --git a/src/ImageProcessorCore/Samplers/Options/ResizeHelper.cs b/src/ImageProcessorCore/Samplers/Options/ResizeHelper.cs index e99bfbbf0a..181b8b5e16 100644 --- a/src/ImageProcessorCore/Samplers/Options/ResizeHelper.cs +++ b/src/ImageProcessorCore/Samplers/Options/ResizeHelper.cs @@ -24,7 +24,7 @@ namespace ImageProcessorCore /// The . /// public static Rectangle CalculateTargetLocationAndBounds(ImageBase source, ResizeOptions options) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { switch (options.Mode) @@ -56,7 +56,7 @@ namespace ImageProcessorCore /// The . /// private static Rectangle CalculateCropRectangle(ImageBase source, ResizeOptions options) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { int width = options.Size.Width; @@ -176,7 +176,7 @@ namespace ImageProcessorCore /// The . /// private static Rectangle CalculatePadRectangle(ImageBase source, ResizeOptions options) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { int width = options.Size.Width; @@ -258,7 +258,7 @@ namespace ImageProcessorCore /// The . /// private static Rectangle CalculateBoxPadRectangle(ImageBase source, ResizeOptions options) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { int width = options.Size.Width; @@ -346,7 +346,7 @@ namespace ImageProcessorCore /// The . /// private static Rectangle CalculateMaxRectangle(ImageBase source, ResizeOptions options) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { int width = options.Size.Width; @@ -388,7 +388,7 @@ namespace ImageProcessorCore /// The . /// private static Rectangle CalculateMinRectangle(ImageBase source, ResizeOptions options) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { int width = options.Size.Width; diff --git a/src/ImageProcessorCore/Samplers/Processors/ResizeProcessor.cs b/src/ImageProcessorCore/Samplers/Processors/ResizeProcessor.cs index 135d0d62f7..6dcec5c572 100644 --- a/src/ImageProcessorCore/Samplers/Processors/ResizeProcessor.cs +++ b/src/ImageProcessorCore/Samplers/Processors/ResizeProcessor.cs @@ -9,8 +9,6 @@ namespace ImageProcessorCore.Processors using System.Numerics; using System.Threading.Tasks; - using ImageProcessorCore.Helpers; - /// /// Provides methods that allow the resizing of images using various algorithms. /// @@ -136,25 +134,6 @@ namespace ImageProcessorCore.Processors Weight[] horizontalValues = this.HorizontalWeights[offsetX].Values; // Destination color components - //Color destination = new Color(); - - //for (int i = 0; i < sum; i++) - //{ - // Weight xw = horizontalValues[i]; - // int originX = xw.Index; - // Color sourceColor = compand - // ? Color.Expand(sourcePixels[originX, y]) - // : sourcePixels[originX, y]; - - // destination += sourceColor * xw.Value; - //} - - //if (compand) - //{ - // destination = Color.Compress(destination); - //} - - //firstPassPixels[x, y] = destination; T destination = default(T); for (int i = 0; i < sum; i++) @@ -162,23 +141,20 @@ namespace ImageProcessorCore.Processors Weight xw = horizontalValues[i]; int originX = xw.Index; T sourceColor = sourcePixels[originX, y]; + //Color sourceColor = compand // ? Color.Expand(sourcePixels[originX, y]) // : sourcePixels[originX, y]; - //sourceColor.Multiply(xw.Value); - //destination.Add(sourceColor); //destination += sourceColor * xw.Value; - //sourceColor.Multiply(xw.Value); - destination.Add(Operator.Add(destination, Operator.MultiplyF(sourceColor, xw.Value))); + sourceColor.Multiply(xw.Value); + destination.Add(sourceColor); } //if (compand) //{ // destination = Color.Compress(destination); //} - //T packed = default(T); - //packed.PackVector(destination); firstPassPixels[x, y] = destination; } @@ -208,16 +184,14 @@ namespace ImageProcessorCore.Processors Weight yw = verticalValues[i]; int originY = yw.Index; T sourceColor = firstPassPixels[x, originY]; + //Color sourceColor = compand // ? Color.Expand(firstPassPixels[x, originY]) // : firstPassPixels[x, originY]; - //Vector4 sourceColor = firstPassPixels[x, originY].ToVector4(); //destination += sourceColor * yw.Value; - //sourceColor.Multiply(yw.Value); - //destination.Add(sourceColor); - destination.Add(Operator.Add(destination, Operator.MultiplyF(sourceColor, yw.Value))); - + sourceColor.Multiply(yw.Value); + destination.Add(sourceColor); } //if (compand) @@ -225,9 +199,6 @@ namespace ImageProcessorCore.Processors // destination = Color.Compress(destination); //} - //T packed = default(T); - //packed.PackVector(destination); - targetPixels[x, y] = destination; } } diff --git a/src/ImageProcessorCore/Samplers/Resize.cs b/src/ImageProcessorCore/Samplers/Resize.cs index 7a08e95bf4..6eec422dba 100644 --- a/src/ImageProcessorCore/Samplers/Resize.cs +++ b/src/ImageProcessorCore/Samplers/Resize.cs @@ -22,7 +22,7 @@ namespace ImageProcessorCore /// The /// Passing zero for one of height or width within the resize options will automatically preserve the aspect ratio of the original image public static Image Resize(this Image source, ResizeOptions options, ProgressEventHandler progressHandler = null) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { // Ensure size is populated across both dimensions. @@ -52,7 +52,7 @@ namespace ImageProcessorCore /// The /// Passing zero for one of height or width will automatically preserve the aspect ratio of the original image public static Image Resize(this Image source, int width, int height, ProgressEventHandler progressHandler = null) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { return Resize(source, width, height, new BicubicResampler(), false, progressHandler); @@ -70,7 +70,7 @@ namespace ImageProcessorCore /// The /// Passing zero for one of height or width will automatically preserve the aspect ratio of the original image public static Image Resize(this Image source, int width, int height, bool compand, ProgressEventHandler progressHandler = null) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { return Resize(source, width, height, new BicubicResampler(), compand, progressHandler); @@ -89,7 +89,7 @@ namespace ImageProcessorCore /// The /// Passing zero for one of height or width will automatically preserve the aspect ratio of the original image public static Image Resize(this Image source, int width, int height, IResampler sampler, bool compand, ProgressEventHandler progressHandler = null) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { return Resize(source, width, height, sampler, source.Bounds, new Rectangle(0, 0, width, height), compand, progressHandler); @@ -115,7 +115,7 @@ namespace ImageProcessorCore /// The /// Passing zero for one of height or width will automatically preserve the aspect ratio of the original image public static Image Resize(this Image source, int width, int height, IResampler sampler, Rectangle sourceRectangle, Rectangle targetRectangle, bool compand = false, ProgressEventHandler progressHandler = null) - where T : IPackedVector, new() + where T : IPackedVector, new() where TP : struct { if (width == 0 && height > 0) diff --git a/src/ImageProcessorCore/project.json b/src/ImageProcessorCore/project.json index 9469f297c1..e3800d495e 100644 --- a/src/ImageProcessorCore/project.json +++ b/src/ImageProcessorCore/project.json @@ -23,7 +23,6 @@ "System.IO": "4.1.0", "System.IO.Compression": "4.1.0", "System.Linq": "4.1.0", - "System.Linq.Expressions": "4.1.0", "System.Numerics.Vectors": "4.1.1", "System.Resources.ResourceManager": "4.0.1", "System.Runtime.Extensions": "4.1.0", diff --git a/tests/ImageProcessorCore.Tests/Processors/Samplers/SamplerTests.cs b/tests/ImageProcessorCore.Tests/Processors/Samplers/SamplerTests.cs index 96f6da0daf..878a9f1ce5 100644 --- a/tests/ImageProcessorCore.Tests/Processors/Samplers/SamplerTests.cs +++ b/tests/ImageProcessorCore.Tests/Processors/Samplers/SamplerTests.cs @@ -114,7 +114,7 @@ namespace ImageProcessorCore.Tests { string filename = Path.GetFileNameWithoutExtension(file) + "-" + name + Path.GetExtension(file); - Image image = new Image(stream); + Image image = new Image(stream); using (FileStream output = File.OpenWrite($"TestOutput/Resize/{filename}")) { image.Resize(image.Width / 2, image.Height / 2, sampler, false, this.ProgressUpdate)