diff --git a/src/ImageProcessorCore - Copy/Bootstrapper.cs b/src/ImageProcessorCore - Copy/Bootstrapper.cs
deleted file mode 100644
index 5f2978534c..0000000000
--- a/src/ImageProcessorCore - Copy/Bootstrapper.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Text;
-
- using ImageProcessorCore.Formats;
-
- ///
- /// Provides initialization code which allows extending the library.
- ///
- public class Bootstrapper
- {
- ///
- /// A new instance Initializes a new instance of the class.
- /// with lazy initialization.
- ///
- private static readonly Lazy Lazy = new Lazy(() => new Bootstrapper());
-
- ///
- /// The default list of supported
- ///
- private readonly List imageFormats;
-
- private readonly Dictionary pixelAccessors;
-
- ///
- /// Prevents a default instance of the class from being created.
- ///
- private Bootstrapper()
- {
- this.imageFormats = new List
- {
- new BmpFormat(),
- new JpegFormat(),
- new PngFormat(),
- new GifFormat()
- };
-
- this.pixelAccessors = new Dictionary
- {
- { typeof(Bgra32), typeof(Bgra32PixelAccessor) }
- };
- }
-
- ///
- /// Gets the current bootstrapper instance.
- ///
- public static Bootstrapper Instance = Lazy.Value;
-
- ///
- /// Gets the list of supported
- ///
- public IReadOnlyCollection ImageFormats => new ReadOnlyCollection(this.imageFormats);
-
- ///
- /// Adds a new to the collection of supported image formats.
- ///
- /// The new format to add.
- public void AddImageFormat(IImageFormat format)
- {
- this.imageFormats.Add(format);
- }
-
- ///
- /// Gets an instance of the correct for the packed vector.
- ///
- /// The type of pixel data.
- /// The image
- /// The
- public IPixelAccessor GetPixelAccessor(Image image)
- where TPackedVector : IPackedVector
- {
- Type packed = typeof(TPackedVector);
- if (!this.pixelAccessors.ContainsKey(packed))
- {
- // TODO: Double check this. It should work...
- return (IPixelAccessor)Activator.CreateInstance(this.pixelAccessors[packed], image);
- }
-
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.AppendLine("PixelAccessor cannot be loaded. Available accessors:");
-
- foreach (Type value in this.pixelAccessors.Values)
- {
- stringBuilder.AppendLine("-" + value.Name);
- }
-
- throw new NotSupportedException(stringBuilder.ToString());
- }
-
- ///
- /// Gets an instance of the correct for the packed vector.
- ///
- /// The type of pixel data.
- /// The image
- /// The
- public IPixelAccessor GetPixelAccessor(ImageFrame image)
- where TPackedVector : IPackedVector
- {
- Type packed = typeof(TPackedVector);
- if (!this.pixelAccessors.ContainsKey(packed))
- {
- return (IPixelAccessor)Activator.CreateInstance(this.pixelAccessors[packed], image);
- }
-
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.AppendLine("PixelAccessor cannot be loaded. Available accessors:");
-
- foreach (Type value in this.pixelAccessors.Values)
- {
- stringBuilder.AppendLine("-" + value.Name);
- }
-
- throw new NotSupportedException(stringBuilder.ToString());
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Colors/Color.cs b/src/ImageProcessorCore - Copy/Colors/Color.cs
deleted file mode 100644
index 0e47e03e1b..0000000000
--- a/src/ImageProcessorCore - Copy/Colors/Color.cs
+++ /dev/null
@@ -1,518 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.ComponentModel;
- using System.Numerics;
- using System.Runtime.CompilerServices;
-
- ///
- /// Represents a four-component color using red, green, blue, and alpha data.
- /// Each component is stored in premultiplied format multiplied by the alpha component.
- ///
- ///
- /// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
- /// as it avoids the need to create new values for modification operations.
- ///
- public partial struct Color : IEquatable, IAlmostEquatable
- {
- ///
- /// Represents an empty that has R, G, B, and A values set to zero.
- ///
- public static readonly Color Empty = default(Color);
-
- ///
- /// The epsilon for comparing floating point numbers.
- ///
- private const float Epsilon = 0.001f;
-
- ///
- /// The backing vector for SIMD support.
- ///
- private Vector4 backingVector;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The red component of this .
- /// The green component of this .
- /// The blue component of this .
- /// The alpha component of this .
- public Color(float r, float g, float b, float a = 1)
- : this()
- {
- this.backingVector = new Vector4(r, g, b, a);
- }
-
- ///
- /// Initializes a new instance of the struct.
- ///
- ///
- /// The hexadecimal representation of the combined color components arranged
- /// in rgb, rrggbb, or aarrggbb format to match web syntax.
- ///
- public Color(string hex)
- : this()
- {
- // Hexadecimal representations are layed out AARRGGBB to we need to do some reordering.
- hex = hex.StartsWith("#") ? hex.Substring(1) : hex;
-
- if (hex.Length != 8 && hex.Length != 6 && hex.Length != 3)
- {
- throw new ArgumentException("Hexadecimal string is not in the correct format.", nameof(hex));
- }
-
- if (hex.Length == 8)
- {
- float r = Convert.ToByte(hex.Substring(2, 2), 16);
- float g = Convert.ToByte(hex.Substring(4, 2), 16);
- float b = Convert.ToByte(hex.Substring(6, 2), 16);
- float a = Convert.ToByte(hex.Substring(0, 2), 16);
-
- // Do division of Vector4 instead of each component to utilize SIMD optimizations
- this.backingVector = new Vector4(r, g, b, a) / 255f;
- this.backingVector = FromNonPremultiplied(this.backingVector, this.A);
-
- }
- else if (hex.Length == 6)
- {
- float r = Convert.ToByte(hex.Substring(0, 2), 16);
- float g = Convert.ToByte(hex.Substring(2, 2), 16);
- float b = Convert.ToByte(hex.Substring(4, 2), 16);
- float a = 255f;
-
- // Do division of Vector4 instead of each component to utilize SIMD optimizations
- this.backingVector = new Vector4(r, g, b, a) / 255f;
- }
- else
- {
- string rh = char.ToString(hex[0]);
- string gh = char.ToString(hex[1]);
- string bh = char.ToString(hex[2]);
-
- float r = Convert.ToByte(rh + rh, 16);
- float g = Convert.ToByte(gh + gh, 16);
- float b = Convert.ToByte(bh + bh, 16);
- float a = 255f;
-
- this.backingVector = new Vector4(r, g, b, a) / 255f;
- }
- }
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The vector.
- public Color(Vector4 vector)
- {
- this.backingVector = vector;
- }
-
- ///
- /// Initializes a new instance of the struct.
- ///
- ///
- /// The vector representing the red, green, and blue componenets.
- ///
- public Color(Vector3 vector)
- {
- this.backingVector = new Vector4(vector, 1);
- }
-
- ///
- /// Initializes a new instance of the struct.
- ///
- ///
- /// The vector representing the red, green, and blue componenets.
- ///
- /// The alpha component.
- public Color(Vector3 vector, float alpha)
- {
- this.backingVector = new Vector4(vector, alpha);
- }
-
- ///
- /// Gets or sets the red component of the color.
- ///
- public float R
- {
- get
- {
- return this.backingVector.X;
- }
-
- set
- {
- this.backingVector.X = value;
- }
- }
-
- ///
- /// Gets or sets the green component of the color.
- ///
- public float G
- {
- get
- {
- return this.backingVector.Y;
- }
-
- set
- {
- this.backingVector.Y = value;
- }
- }
-
- ///
- /// Gets or sets the blue component of the color.
- ///
- public float B
- {
- get
- {
- return this.backingVector.Z;
- }
-
- set
- {
- this.backingVector.Z = value;
- }
- }
-
- ///
- /// Gets or sets the alpha component of the color.
- ///
- public float A
- {
- get
- {
- return this.backingVector.W;
- }
-
- set
- {
- this.backingVector.W = value;
- }
- }
-
- ///
- /// Gets a value indicating whether this is empty.
- ///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public bool IsEmpty => this.Equals(Empty);
-
- ///
- /// Gets this color with the component values clamped from 0 to 1.
- ///
- public Color Limited => new Color(Vector4.Clamp(this.backingVector, Vector4.Zero, Vector4.One));
-
- ///
- /// Computes the product of multiplying a color by a given factor.
- ///
- /// The color.
- /// The multiplication factor.
- ///
- /// The
- ///
- public static Color operator *(Color color, float factor)
- {
- return new Color(color.backingVector * factor);
- }
-
- ///
- /// Computes the product of multiplying a color by a given factor.
- ///
- /// The multiplication factor.
- /// The color.
- ///
- /// The
- ///
- public static Color operator *(float factor, Color color)
- {
- return new Color(color.backingVector * factor);
- }
-
- ///
- /// Computes the product of multiplying two colors.
- ///
- /// The color on the left hand of the operand.
- /// The color on the right hand of the operand.
- ///
- /// The
- ///
- public static Color operator *(Color left, Color right)
- {
- return new Color(left.backingVector * right.backingVector);
- }
-
- ///
- /// Computes the sum of adding two colors.
- ///
- /// The color on the left hand of the operand.
- /// The color on the right hand of the operand.
- ///
- /// The
- ///
- public static Color operator +(Color left, Color right)
- {
- return new Color(left.backingVector + right.backingVector);
- }
-
- ///
- /// Computes the difference left by subtracting one color from another.
- ///
- /// The color on the left hand of the operand.
- /// The color on the right hand of the operand.
- ///
- /// The
- ///
- public static Color operator -(Color left, Color right)
- {
- return new Color(left.backingVector - right.backingVector);
- }
-
- ///
- /// 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 ==(Color left, Color right)
- {
- return left.Equals(right);
- }
-
- ///
- /// Compares two objects for inequality.
- ///
- ///
- /// The on the left side of the operand.
- ///
- ///
- /// The on the right side of the operand.
- ///
- ///
- /// True if the current left is unequal to the parameter; otherwise, false.
- ///
- public static bool operator !=(Color left, Color right)
- {
- return !left.Equals(right);
- }
-
- ///
- /// Returns a new color whose components are the average of the components of first and second.
- ///
- /// The first color.
- /// The second color.
- ///
- /// The
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Color Average(Color first, Color second)
- {
- return new Color((first.backingVector + second.backingVector) * .5f);
- }
-
- ///
- /// Compresses a linear color signal to its sRGB equivalent.
- ///
- ///
- ///
- /// The whose signal to compress.
- /// The .
- public static Color Compress(Color linear)
- {
- // TODO: Is there a faster way to do this?
- float r = Compress(linear.R);
- float g = Compress(linear.G);
- float b = Compress(linear.B);
-
- return new Color(r, g, b, linear.A);
- }
-
- ///
- /// Expands an sRGB color signal to its linear equivalent.
- ///
- ///
- ///
- /// The whose signal to expand.
- /// The .
- public static Color Expand(Color gamma)
- {
- // TODO: Is there a faster way to do this?
- float r = Expand(gamma.R);
- float g = Expand(gamma.G);
- float b = Expand(gamma.B);
-
- return new Color(r, g, b, gamma.A);
- }
-
- ///
- /// Converts a non-premultipled alpha to a
- /// that contains premultiplied alpha.
- ///
- /// The to convert.
- /// The .
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Color FromNonPremultiplied(Color color)
- {
- return new Color(FromNonPremultiplied(color.backingVector, color.A));
- }
-
- ///
- /// Converts a non-premultiplied alpha Vector4 to a Vector4 that contains premultiplied alpha.
- ///
- /// The vector to convert.
- /// The alpha to use in conversion.
- /// The Vector4 with premultiplied alpha.
- private static Vector4 FromNonPremultiplied(Vector4 vector, float alpha)
- {
- return vector * new Vector4(alpha, alpha, alpha, 1);
- }
-
- ///
- /// Converts a premultipled alpha to a
- /// that contains non-premultiplied alpha.
- ///
- /// The to convert.
- /// The .
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static Color ToNonPremultiplied(Color color)
- {
- float a = color.A;
- if (Math.Abs(a) < Epsilon)
- {
- return new Color(color.backingVector);
- }
-
- return new Color(color.backingVector / new Vector4(a, a, a, 1));
- }
-
- ///
- /// Gets a representation for this .
- ///
- /// A representation for this object.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Vector4 ToVector4()
- {
- return new Vector4(this.R, this.G, this.B, this.A);
- }
-
- ///
- /// Gets a representation for this .
- ///
- /// A representation for this object.
- public Vector3 ToVector3()
- {
- return new Vector3(this.R, this.G, this.B);
- }
-
- ///
- public override int GetHashCode()
- {
- return GetHashCode(this);
- }
-
- ///
- public override string ToString()
- {
- if (this.IsEmpty)
- {
- return "Color [ Empty ]";
- }
-
- return $"Color [ R={this.R:#0.##}, G={this.G:#0.##}, B={this.B:#0.##}, A={this.A:#0.##} ]";
- }
-
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public override bool Equals(object obj)
- {
- if (obj is Color)
- {
- return this.Equals((Color)obj);
- }
-
- return false;
- }
-
- ///
- public bool Equals(Color other)
- {
- return this.AlmostEquals(other, Epsilon);
- }
-
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public bool AlmostEquals(Color other, float precision)
- {
- Vector4 result = Vector4.Abs(this.backingVector - other.backingVector);
-
- return result.X < precision
- && result.Y < precision
- && result.Z < precision
- && result.W < precision;
- }
-
- ///
- /// Gets the compressed sRGB value from an linear signal.
- ///
- ///
- ///
- /// The signal value to compress.
- ///
- /// The .
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static float Compress(float signal)
- {
- if (signal <= 0.0031308f)
- {
- return signal * 12.92f;
- }
-
- return (1.055f * (float)Math.Pow(signal, 0.41666666f)) - 0.055f;
- }
-
- ///
- /// Gets the expanded linear value from an sRGB signal.
- ///
- ///
- ///
- /// The signal value to expand.
- ///
- /// The .
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static float Expand(float signal)
- {
- if (signal <= 0.04045f)
- {
- return signal / 12.92f;
- }
-
- return (float)Math.Pow((signal + 0.055f) / 1.055f, 2.4f);
- }
-
- ///
- /// 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 static int GetHashCode(Color color) => color.backingVector.GetHashCode();
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Colors/ColorConstants.cs b/src/ImageProcessorCore - Copy/Colors/ColorConstants.cs
deleted file mode 100644
index ed9718423d..0000000000
--- a/src/ImageProcessorCore - Copy/Colors/ColorConstants.cs
+++ /dev/null
@@ -1,179 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.Collections.Generic;
-
- ///
- /// Provides useful color definitions.
- ///
- public static class ColorConstants
- {
- ///
- /// Provides a lazy, one time method of returning the colors.
- ///
- private static readonly Lazy SafeColors = new Lazy(GetWebSafeColors);
-
- ///
- /// Gets a collection of named, web safe, colors as defined in the CSS Color Module Level 4.
- ///
- public static Color[] WebSafeColors => SafeColors.Value;
-
- ///
- /// Returns an array of web safe colors.
- ///
- ///
- private static Color[] GetWebSafeColors()
- {
- return new List
- {
- Color.AliceBlue,
- Color.AntiqueWhite,
- Color.Aqua,
- Color.Aquamarine,
- Color.Azure,
- Color.Beige,
- Color.Bisque,
- Color.Black,
- Color.BlanchedAlmond,
- Color.Blue,
- Color.BlueViolet,
- Color.Brown,
- Color.BurlyWood,
- Color.CadetBlue,
- Color.Chartreuse,
- Color.Chocolate,
- Color.Coral,
- Color.CornflowerBlue,
- Color.Cornsilk,
- Color.Crimson,
- Color.Cyan,
- Color.DarkBlue,
- Color.DarkCyan,
- Color.DarkGoldenrod,
- Color.DarkGray,
- Color.DarkGreen,
- Color.DarkKhaki,
- Color.DarkMagenta,
- Color.DarkOliveGreen,
- Color.DarkOrange,
- Color.DarkOrchid,
- Color.DarkRed,
- Color.DarkSalmon,
- Color.DarkSeaGreen,
- Color.DarkSlateBlue,
- Color.DarkSlateGray,
- Color.DarkTurquoise,
- Color.DarkViolet,
- Color.DeepPink,
- Color.DeepSkyBlue,
- Color.DimGray,
- Color.DodgerBlue,
- Color.Firebrick,
- Color.FloralWhite,
- Color.ForestGreen,
- Color.Fuchsia,
- Color.Gainsboro,
- Color.GhostWhite,
- Color.Gold,
- Color.Goldenrod,
- Color.Gray,
- Color.Green,
- Color.GreenYellow,
- Color.Honeydew,
- Color.HotPink,
- Color.IndianRed,
- Color.Indigo,
- Color.Ivory,
- Color.Khaki,
- Color.Lavender,
- Color.LavenderBlush,
- Color.LawnGreen,
- Color.LemonChiffon,
- Color.LightBlue,
- Color.LightCoral,
- Color.LightCyan,
- Color.LightGoldenrodYellow,
- Color.LightGray,
- Color.LightGreen,
- Color.LightPink,
- Color.LightSalmon,
- Color.LightSeaGreen,
- Color.LightSkyBlue,
- Color.LightSlateGray,
- Color.LightSteelBlue,
- Color.LightYellow,
- Color.Lime,
- Color.LimeGreen,
- Color.Linen,
- Color.Magenta,
- Color.Maroon,
- Color.MediumAquamarine,
- Color.MediumBlue,
- Color.MediumOrchid,
- Color.MediumPurple,
- Color.MediumSeaGreen,
- Color.MediumSlateBlue,
- Color.MediumSpringGreen,
- Color.MediumTurquoise,
- Color.MediumVioletRed,
- Color.MidnightBlue,
- Color.MintCream,
- Color.MistyRose,
- Color.Moccasin,
- Color.NavajoWhite,
- Color.Navy,
- Color.OldLace,
- Color.Olive,
- Color.OliveDrab,
- Color.Orange,
- Color.OrangeRed,
- Color.Orchid,
- Color.PaleGoldenrod,
- Color.PaleGreen,
- Color.PaleTurquoise,
- Color.PaleVioletRed,
- Color.PapayaWhip,
- Color.PeachPuff,
- Color.Peru,
- Color.Pink,
- Color.Plum,
- Color.PowderBlue,
- Color.Purple,
- Color.RebeccaPurple,
- Color.Red,
- Color.RosyBrown,
- Color.RoyalBlue,
- Color.SaddleBrown,
- Color.Salmon,
- Color.SandyBrown,
- Color.SeaGreen,
- Color.SeaShell,
- Color.Sienna,
- Color.Silver,
- Color.SkyBlue,
- Color.SlateBlue,
- Color.SlateGray,
- Color.Snow,
- Color.SpringGreen,
- Color.SteelBlue,
- Color.Tan,
- Color.Teal,
- Color.Thistle,
- Color.Tomato,
- Color.Transparent,
- Color.Turquoise,
- Color.Violet,
- Color.Wheat,
- Color.White,
- Color.WhiteSmoke,
- Color.Yellow,
- Color.YellowGreen
- }.ToArray();
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Colors/ColorDefinitions.cs b/src/ImageProcessorCore - Copy/Colors/ColorDefinitions.cs
deleted file mode 100644
index aaf99bb1b3..0000000000
--- a/src/ImageProcessorCore - Copy/Colors/ColorDefinitions.cs
+++ /dev/null
@@ -1,728 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// Represents a four-component color using red, green, blue, and alpha data.
- /// Each component is stored in premultiplied format multiplied by the alpha component.
- ///
- ///
- /// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
- /// as it avoids the need to create new values for modification operations.
- ///
- public partial struct Color
- {
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #F0F8FF.
- ///
- public static readonly Color AliceBlue = new Color(240 / 255f, 248 / 255f, 1);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FAEBD7.
- ///
- public static readonly Color AntiqueWhite = new Color(250 / 255f, 235 / 255f, 215 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #00FFFF.
- ///
- public static readonly Color Aqua = new Color(0, 1, 1);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #7FFFD4.
- ///
- public static readonly Color Aquamarine = new Color(127 / 255f, 1, 212 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #F0FFFF.
- ///
- public static readonly Color Azure = new Color(240 / 255f, 1, 1);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #F5F5DC.
- ///
- public static readonly Color Beige = new Color(245 / 255f, 245 / 255f, 220 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFE4C4.
- ///
- public static readonly Color Bisque = new Color(1, 228 / 255f, 196 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #000000.
- ///
- public static readonly Color Black = new Color(0, 0, 0);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFEBCD.
- ///
- public static readonly Color BlanchedAlmond = new Color(1, 235 / 255f, 205 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #0000FF.
- ///
- public static readonly Color Blue = new Color(0, 0, 1);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #8A2BE2.
- ///
- public static readonly Color BlueViolet = new Color(138 / 255f, 43 / 255f, 226 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #A52A2A.
- ///
- public static readonly Color Brown = new Color(165 / 255f, 42 / 255f, 42 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #DEB887.
- ///
- public static readonly Color BurlyWood = new Color(222 / 255f, 184 / 255f, 135 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #5F9EA0.
- ///
- public static readonly Color CadetBlue = new Color(95 / 255f, 158 / 255f, 160 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #7FFF00.
- ///
- public static readonly Color Chartreuse = new Color(127 / 255f, 1, 0);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #D2691E.
- ///
- public static readonly Color Chocolate = new Color(210 / 255f, 105 / 255f, 30 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FF7F50.
- ///
- public static readonly Color Coral = new Color(1, 127 / 255f, 80 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #6495ED.
- ///
- public static readonly Color CornflowerBlue = new Color(100 / 255f, 149 / 255f, 237 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFF8DC.
- ///
- public static readonly Color Cornsilk = new Color(1, 248 / 255f, 220 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #DC143C.
- ///
- public static readonly Color Crimson = new Color(220 / 255f, 20 / 255f, 60 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #00FFFF.
- ///
- public static readonly Color Cyan = new Color(0, 1, 1);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #00008B.
- ///
- public static readonly Color DarkBlue = new Color(0, 0, 139 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #008B8B.
- ///
- public static readonly Color DarkCyan = new Color(0, 139 / 255f, 139 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #B8860B.
- ///
- public static readonly Color DarkGoldenrod = new Color(184 / 255f, 134 / 255f, 11 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #A9A9A9.
- ///
- public static readonly Color DarkGray = new Color(169 / 255f, 169 / 255f, 169 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #006400.
- ///
- public static readonly Color DarkGreen = new Color(0, 100 / 255f, 0);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #BDB76B.
- ///
- public static readonly Color DarkKhaki = new Color(189 / 255f, 183 / 255f, 107 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #8B008B.
- ///
- public static readonly Color DarkMagenta = new Color(139 / 255f, 0, 139 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #556B2F.
- ///
- public static readonly Color DarkOliveGreen = new Color(85 / 255f, 107 / 255f, 47 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FF8C00.
- ///
- public static readonly Color DarkOrange = new Color(1, 140 / 255f, 0);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #9932CC.
- ///
- public static readonly Color DarkOrchid = new Color(153 / 255f, 50 / 255f, 204 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #8B0000.
- ///
- public static readonly Color DarkRed = new Color(139 / 255f, 0, 0);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #E9967A.
- ///
- public static readonly Color DarkSalmon = new Color(233 / 255f, 150 / 255f, 122 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #8FBC8B.
- ///
- public static readonly Color DarkSeaGreen = new Color(143 / 255f, 188 / 255f, 139 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #483D8B.
- ///
- public static readonly Color DarkSlateBlue = new Color(72 / 255f, 61 / 255f, 139 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #2F4F4F.
- ///
- public static readonly Color DarkSlateGray = new Color(47 / 255f, 79 / 255f, 79 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #00CED1.
- ///
- public static readonly Color DarkTurquoise = new Color(0, 206 / 255f, 209 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #9400D3.
- ///
- public static readonly Color DarkViolet = new Color(148 / 255f, 0, 211 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FF1493.
- ///
- public static readonly Color DeepPink = new Color(1, 20 / 255f, 147 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #00BFFF.
- ///
- public static readonly Color DeepSkyBlue = new Color(0, 191 / 255f, 1);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #696969.
- ///
- public static readonly Color DimGray = new Color(105 / 255f, 105 / 255f, 105 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #1E90FF.
- ///
- public static readonly Color DodgerBlue = new Color(30 / 255f, 144 / 255f, 1);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #B22222.
- ///
- public static readonly Color Firebrick = new Color(178 / 255f, 34 / 255f, 34 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFFAF0.
- ///
- public static readonly Color FloralWhite = new Color(1, 250 / 255f, 240 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #228B22.
- ///
- public static readonly Color ForestGreen = new Color(34 / 255f, 139 / 255f, 34 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FF00FF.
- ///
- public static readonly Color Fuchsia = new Color(1, 0, 1);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #DCDCDC.
- ///
- public static readonly Color Gainsboro = new Color(220 / 255f, 220 / 255f, 220 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #F8F8FF.
- ///
- public static readonly Color GhostWhite = new Color(248 / 255f, 248 / 255f, 1);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFD700.
- ///
- public static readonly Color Gold = new Color(1, 215 / 255f, 0);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #DAA520.
- ///
- public static readonly Color Goldenrod = new Color(218 / 255f, 165 / 255f, 32 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #808080.
- ///
- public static readonly Color Gray = new Color(128 / 255f, 128 / 255f, 128 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #008000.
- ///
- public static readonly Color Green = new Color(0, 128 / 255f, 0);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #ADFF2F.
- ///
- public static readonly Color GreenYellow = new Color(173 / 255f, 1, 47 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #F0FFF0.
- ///
- public static readonly Color Honeydew = new Color(240 / 255f, 1, 240 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FF69B4.
- ///
- public static readonly Color HotPink = new Color(1, 105 / 255f, 180 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #CD5C5C.
- ///
- public static readonly Color IndianRed = new Color(205 / 255f, 92 / 255f, 92 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #4B0082.
- ///
- public static readonly Color Indigo = new Color(75 / 255f, 0, 130 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFFFF0.
- ///
- public static readonly Color Ivory = new Color(1, 1, 240 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #F0E68C.
- ///
- public static readonly Color Khaki = new Color(240 / 255f, 230 / 255f, 140 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #E6E6FA.
- ///
- public static readonly Color Lavender = new Color(230 / 255f, 230 / 255f, 250 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFF0F5.
- ///
- public static readonly Color LavenderBlush = new Color(1, 240 / 255f, 245 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #7CFC00.
- ///
- public static readonly Color LawnGreen = new Color(124 / 255f, 252 / 255f, 0);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFFACD.
- ///
- public static readonly Color LemonChiffon = new Color(1, 250 / 255f, 205 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #ADD8E6.
- ///
- public static readonly Color LightBlue = new Color(173 / 255f, 216 / 255f, 230 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #F08080.
- ///
- public static readonly Color LightCoral = new Color(240 / 255f, 128 / 255f, 128 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #E0FFFF.
- ///
- public static readonly Color LightCyan = new Color(224 / 255f, 1, 1);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FAFAD2.
- ///
- public static readonly Color LightGoldenrodYellow = new Color(250 / 255f, 250 / 255f, 210 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #90EE90.
- ///
- public static readonly Color LightGreen = new Color(144 / 255f, 238 / 255f, 144 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #D3D3D3.
- ///
- public static readonly Color LightGray = new Color(211 / 255f, 211 / 255f, 211 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFB6C1.
- ///
- public static readonly Color LightPink = new Color(1, 182 / 255f, 193 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFA07A.
- ///
- public static readonly Color LightSalmon = new Color(1, 160 / 255f, 122 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #20B2AA.
- ///
- public static readonly Color LightSeaGreen = new Color(32 / 255f, 178 / 255f, 170 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #87CEFA.
- ///
- public static readonly Color LightSkyBlue = new Color(135 / 255f, 206 / 255f, 250 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #778899.
- ///
- public static readonly Color LightSlateGray = new Color(119 / 255f, 136 / 255f, 153 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #B0C4DE.
- ///
- public static readonly Color LightSteelBlue = new Color(176 / 255f, 196 / 255f, 222 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFFFE0.
- ///
- public static readonly Color LightYellow = new Color(1, 1, 224 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #00FF00.
- ///
- public static readonly Color Lime = new Color(0, 1, 0);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #32CD32.
- ///
- public static readonly Color LimeGreen = new Color(50 / 255f, 205 / 255f, 50 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FAF0E6.
- ///
- public static readonly Color Linen = new Color(250 / 255f, 240 / 255f, 230 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FF00FF.
- ///
- public static readonly Color Magenta = new Color(1, 0, 1);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #800000.
- ///
- public static readonly Color Maroon = new Color(128 / 255f, 0, 0);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #66CDAA.
- ///
- public static readonly Color MediumAquamarine = new Color(102 / 255f, 205 / 255f, 170 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #0000CD.
- ///
- public static readonly Color MediumBlue = new Color(0, 0, 205 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #BA55D3.
- ///
- public static readonly Color MediumOrchid = new Color(186 / 255f, 85 / 255f, 211 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #9370DB.
- ///
- public static readonly Color MediumPurple = new Color(147 / 255f, 112 / 255f, 219 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #3CB371.
- ///
- public static readonly Color MediumSeaGreen = new Color(60 / 255f, 179 / 255f, 113 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #7B68EE.
- ///
- public static readonly Color MediumSlateBlue = new Color(123 / 255f, 104 / 255f, 238 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #00FA9A.
- ///
- public static readonly Color MediumSpringGreen = new Color(0, 250 / 255f, 154 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #48D1CC.
- ///
- public static readonly Color MediumTurquoise = new Color(72 / 255f, 209 / 255f, 204 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #C71585.
- ///
- public static readonly Color MediumVioletRed = new Color(199 / 255f, 21 / 255f, 133 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #191970.
- ///
- public static readonly Color MidnightBlue = new Color(25 / 255f, 25 / 255f, 112 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #F5FFFA.
- ///
- public static readonly Color MintCream = new Color(245 / 255f, 1, 250 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFE4E1.
- ///
- public static readonly Color MistyRose = new Color(1, 228 / 255f, 225 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFE4B5.
- ///
- public static readonly Color Moccasin = new Color(1, 228 / 255f, 181 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFDEAD.
- ///
- public static readonly Color NavajoWhite = new Color(1, 222 / 255f, 173 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #000080.
- ///
- public static readonly Color Navy = new Color(0, 0, 128 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FDF5E6.
- ///
- public static readonly Color OldLace = new Color(253 / 255f, 245 / 255f, 230 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #808000.
- ///
- public static readonly Color Olive = new Color(128 / 255f, 128 / 255f, 0);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #6B8E23.
- ///
- public static readonly Color OliveDrab = new Color(107 / 255f, 142 / 255f, 35 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFA500.
- ///
- public static readonly Color Orange = new Color(1, 165 / 255f, 0);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FF4500.
- ///
- public static readonly Color OrangeRed = new Color(1, 69 / 255f, 0);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #DA70D6.
- ///
- public static readonly Color Orchid = new Color(218 / 255f, 112 / 255f, 214 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #EEE8AA.
- ///
- public static readonly Color PaleGoldenrod = new Color(238 / 255f, 232 / 255f, 170 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #98FB98.
- ///
- public static readonly Color PaleGreen = new Color(152 / 255f, 251 / 255f, 152 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #AFEEEE.
- ///
- public static readonly Color PaleTurquoise = new Color(175 / 255f, 238 / 255f, 238 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #DB7093.
- ///
- public static readonly Color PaleVioletRed = new Color(219 / 255f, 112 / 255f, 147 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFEFD5.
- ///
- public static readonly Color PapayaWhip = new Color(1, 239 / 255f, 213 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFDAB9.
- ///
- public static readonly Color PeachPuff = new Color(1, 218 / 255f, 185 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #CD853F.
- ///
- public static readonly Color Peru = new Color(205 / 255f, 133 / 255f, 63 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFC0CB.
- ///
- public static readonly Color Pink = new Color(1, 192 / 255f, 203 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #DDA0DD.
- ///
- public static readonly Color Plum = new Color(221 / 255f, 160 / 255f, 221 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #B0E0E6.
- ///
- public static readonly Color PowderBlue = new Color(176 / 255f, 224 / 255f, 230 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #800080.
- ///
- public static readonly Color Purple = new Color(128 / 255f, 0, 128 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #663399.
- ///
- public static readonly Color RebeccaPurple = new Color(102 / 255f, 51 / 255f, 153 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FF0000.
- ///
- public static readonly Color Red = new Color(1, 0, 0);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #BC8F8F.
- ///
- public static readonly Color RosyBrown = new Color(188 / 255f, 143 / 255f, 143 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #4169E1.
- ///
- public static readonly Color RoyalBlue = new Color(65 / 255f, 105 / 255f, 225 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #8B4513.
- ///
- public static readonly Color SaddleBrown = new Color(139 / 255f, 69 / 255f, 19 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FA8072.
- ///
- public static readonly Color Salmon = new Color(250 / 255f, 128 / 255f, 114 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #F4A460.
- ///
- public static readonly Color SandyBrown = new Color(244 / 255f, 164 / 255f, 96 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #2E8B57.
- ///
- public static readonly Color SeaGreen = new Color(46 / 255f, 139 / 255f, 87 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFF5EE.
- ///
- public static readonly Color SeaShell = new Color(1, 245 / 255f, 238 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #A0522D.
- ///
- public static readonly Color Sienna = new Color(160 / 255f, 82 / 255f, 45 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #C0C0C0.
- ///
- public static readonly Color Silver = new Color(192 / 255f, 192 / 255f, 192 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #87CEEB.
- ///
- public static readonly Color SkyBlue = new Color(135 / 255f, 206 / 255f, 235 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #6A5ACD.
- ///
- public static readonly Color SlateBlue = new Color(106 / 255f, 90 / 255f, 205 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #708090.
- ///
- public static readonly Color SlateGray = new Color(112 / 255f, 128 / 255f, 144 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFFAFA.
- ///
- public static readonly Color Snow = new Color(1, 250 / 255f, 250 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #00FF7F.
- ///
- public static readonly Color SpringGreen = new Color(0, 1, 127 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #4682B4.
- ///
- public static readonly Color SteelBlue = new Color(70 / 255f, 130 / 255f, 180 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #D2B48C.
- ///
- public static readonly Color Tan = new Color(210 / 255f, 180 / 255f, 140 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #008080.
- ///
- public static readonly Color Teal = new Color(0, 128 / 255f, 128 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #D8BFD8.
- ///
- public static readonly Color Thistle = new Color(216 / 255f, 191 / 255f, 216 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FF6347.
- ///
- public static readonly Color Tomato = new Color(1, 99 / 255f, 71 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #40E0D0.
- ///
- public static readonly Color Turquoise = new Color(64 / 255f, 224 / 255f, 208 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #EE82EE.
- ///
- public static readonly Color Violet = new Color(238 / 255f, 130 / 255f, 238 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #F5DEB3.
- ///
- public static readonly Color Wheat = new Color(245 / 255f, 222 / 255f, 179 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFFFFF.
- ///
- public static readonly Color White = new Color(1, 1, 1);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #F5F5F5.
- ///
- public static readonly Color WhiteSmoke = new Color(245 / 255f, 245 / 255f, 245 / 255f);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #FFFF00.
- ///
- public static readonly Color Yellow = new Color(1, 1, 0);
-
- ///
- /// Represents a matching the W3C definition that has a hex triplet value of #9ACD32.
- ///
- public static readonly Color YellowGreen = new Color(154 / 255f, 205 / 255f, 50 / 255f);
-
- ///
- /// Represents a system-defined that has an ARGB value of #00FFFFFF.
- ///
- public static readonly Color Transparent = new Color(1, 1, 1, 0);
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Colors/ColorTransforms.cs b/src/ImageProcessorCore - Copy/Colors/ColorTransforms.cs
deleted file mode 100644
index 2a0da9407f..0000000000
--- a/src/ImageProcessorCore - Copy/Colors/ColorTransforms.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
-
- ///
- /// Represents a four-component color using red, green, blue, and alpha data.
- /// Each component is stored in premultiplied format multiplied by the alpha component.
- ///
- ///
- /// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
- /// as it avoids the need to create new values for modification operations.
- ///
- public partial struct Color
- {
- ///
- /// Blends two colors by multiplication.
- ///
- /// The source color is multiplied by the destination color and replaces the destination.
- /// The resultant color is always at least as dark as either the source or destination color.
- /// Multiplying any color with black results in black. Multiplying any color with white preserves the
- /// original color.
- ///
- ///
- /// The source color.
- /// The destination color.
- ///
- /// The .
- ///
- public static Color Multiply(Color source, Color destination)
- {
- if (destination == Color.Black)
- {
- return Color.Black;
- }
-
- if (destination == Color.White)
- {
- return source;
- }
-
- return new Color(source.backingVector * destination.backingVector);
- }
-
- ///
- /// Linearly interpolates from one color to another based on the given amount.
- ///
- /// The first color value.
- /// The second color value.
- ///
- /// The weight value. At amount = 0, "from" is returned, at amount = 1, "to" is returned.
- ///
- ///
- /// The
- ///
- public static Color Lerp(Color source, Color destination, float amount)
- {
- amount = amount.Clamp(0f, 1f);
-
- if (Math.Abs(source.A - 1) < Epsilon && Math.Abs(destination.A - 1) < Epsilon)
- {
- return source + ((destination - source) * amount);
- }
-
- // Premultiplied.
- return (source * (1 - amount)) + destination;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Colors/ColorspaceTransforms.cs b/src/ImageProcessorCore - Copy/Colors/ColorspaceTransforms.cs
deleted file mode 100644
index 50d0af3150..0000000000
--- a/src/ImageProcessorCore - Copy/Colors/ColorspaceTransforms.cs
+++ /dev/null
@@ -1,285 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
-
- ///
- /// Represents a four-component color using red, green, blue, and alpha data.
- /// Each component is stored in premultiplied format multiplied by the alpha component.
- ///
- ///
- /// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
- /// as it avoids the need to create new values for modification operations.
- ///
- public partial struct Color
- {
- ///
- /// Allows the implicit conversion of an instance of to a
- /// .
- ///
- /// The instance of to convert.
- ///
- /// An instance of .
- ///
- public static implicit operator Color(Bgra32 color)
- {
- return new Color(color.R / 255f, color.G / 255f, color.B / 255f, color.A / 255f);
- }
-
- ///
- /// Allows the implicit conversion of an instance of to a
- /// .
- ///
- /// The instance of to convert.
- ///
- /// An instance of .
- ///
- public static implicit operator Color(Cmyk cmykColor)
- {
- float r = (1 - cmykColor.C) * (1 - cmykColor.K);
- float g = (1 - cmykColor.M) * (1 - cmykColor.K);
- float b = (1 - cmykColor.Y) * (1 - cmykColor.K);
- return new Color(r, g, b);
- }
-
- ///
- /// Allows the implicit conversion of an instance of to a
- /// .
- ///
- /// The instance of to convert.
- ///
- /// An instance of .
- ///
- public static implicit operator Color(YCbCr color)
- {
- float y = color.Y;
- float cb = color.Cb - 128;
- float cr = color.Cr - 128;
-
- float r = (float)(y + (1.402 * cr)).Clamp(0, 255) / 255f;
- float g = (float)(y - (0.34414 * cb) - (0.71414 * cr)).Clamp(0, 255) / 255f;
- float b = (float)(y + (1.772 * cb)).Clamp(0, 255) / 255f;
-
- return new Color(r, g, b);
- }
-
- ///
- /// Allows the implicit conversion of an instance of to a
- /// .
- ///
- /// The instance of to convert.
- ///
- /// An instance of .
- ///
- public static implicit operator Color(CieXyz color)
- {
- float x = color.X / 100F;
- float y = color.Y / 100F;
- float z = color.Z / 100F;
-
- // Then XYZ to RGB (multiplication by 100 was done above already)
- float r = (x * 3.2406F) + (y * -1.5372F) + (z * -0.4986F);
- float g = (x * -0.9689F) + (y * 1.8758F) + (z * 0.0415F);
- float b = (x * 0.0557F) + (y * -0.2040F) + (z * 1.0570F);
-
- return Color.Compress(new Color(r, g, b));
- }
-
- ///
- /// Allows the implicit conversion of an instance of to a
- /// .
- ///
- /// The instance of to convert.
- ///
- /// An instance of .
- ///
- public static implicit operator Color(Hsv color)
- {
- float s = color.S;
- float v = color.V;
-
- if (Math.Abs(s) < Epsilon)
- {
- return new Color(v, v, v, 1);
- }
-
- float h = (Math.Abs(color.H - 360) < Epsilon) ? 0 : color.H / 60;
- int i = (int)Math.Truncate(h);
- float f = h - i;
-
- float p = v * (1.0f - s);
- float q = v * (1.0f - (s * f));
- float t = v * (1.0f - (s * (1.0f - f)));
-
- float r, g, b;
- switch (i)
- {
- case 0:
- r = v;
- g = t;
- b = p;
- break;
-
- case 1:
- r = q;
- g = v;
- b = p;
- break;
-
- case 2:
- r = p;
- g = v;
- b = t;
- break;
-
- case 3:
- r = p;
- g = q;
- b = v;
- break;
-
- case 4:
- r = t;
- g = p;
- b = v;
- break;
-
- default:
- r = v;
- g = p;
- b = q;
- break;
- }
-
- return new Color(r, g, b);
- }
-
- ///
- /// Allows the implicit conversion of an instance of to a
- /// .
- ///
- /// The instance of to convert.
- ///
- /// An instance of .
- ///
- public static implicit operator Color(Hsl color)
- {
- float rangedH = color.H / 360f;
- float r = 0;
- float g = 0;
- float b = 0;
- float s = color.S;
- float l = color.L;
-
- if (Math.Abs(l) > Epsilon)
- {
- if (Math.Abs(s) < Epsilon)
- {
- r = g = b = l;
- }
- else
- {
- float temp2 = (l < 0.5f) ? l * (1f + s) : l + s - (l * s);
- float temp1 = (2f * l) - temp2;
-
- r = GetColorComponent(temp1, temp2, rangedH + 0.3333333F);
- g = GetColorComponent(temp1, temp2, rangedH);
- b = GetColorComponent(temp1, temp2, rangedH - 0.3333333F);
- }
- }
-
- return new Color(r, g, b);
- }
-
- ///
- /// Allows the implicit conversion of an instance of to a
- /// .
- ///
- /// The instance of to convert.
- ///
- /// An instance of .
- ///
- public static implicit operator Color(CieLab cieLabColor)
- {
- // First convert back to XYZ...
- float y = (cieLabColor.L + 16F) / 116F;
- float x = (cieLabColor.A / 500F) + y;
- float z = y - (cieLabColor.B / 200F);
-
- float x3 = x * x * x;
- float y3 = y * y * y;
- float z3 = z * z * z;
-
- x = x3 > 0.008856F ? x3 : (x - 0.137931F) / 7.787F;
- y = (cieLabColor.L > 7.999625F) ? y3 : (cieLabColor.L / 903.3F);
- z = (z3 > 0.008856F) ? z3 : (z - 0.137931F) / 7.787F;
-
- x *= 0.95047F;
- z *= 1.08883F;
-
- // Then XYZ to RGB (multiplication by 100 was done above already)
- float r = (x * 3.2406F) + (y * -1.5372F) + (z * -0.4986F);
- float g = (x * -0.9689F) + (y * 1.8758F) + (z * 0.0415F);
- float b = (x * 0.0557F) + (y * -0.2040F) + (z * 1.0570F);
-
- return Color.Compress(new Color(r, g, b));
- }
-
- ///
- /// Gets the color component from the given values.
- ///
- /// The first value.
- /// The second value.
- /// The third value.
- ///
- /// The .
- ///
- private static float GetColorComponent(float first, float second, float third)
- {
- third = MoveIntoRange(third);
- if (third < 0.1666667F)
- {
- return first + ((second - first) * 6.0f * third);
- }
-
- if (third < 0.5)
- {
- return second;
- }
-
- if (third < 0.6666667F)
- {
- return first + ((second - first) * (0.6666667F - third) * 6.0f);
- }
-
- return first;
- }
-
- ///
- /// Moves the specific value within the acceptable range for
- /// conversion.
- /// Used for converting colors to this type.
- ///
- /// The value to shift.
- ///
- /// The .
- ///
- private static float MoveIntoRange(float value)
- {
- if (value < 0.0)
- {
- value += 1.0f;
- }
- else if (value > 1.0)
- {
- value -= 1.0f;
- }
-
- return value;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Colors/Colorspaces/Bgra32.cs b/src/ImageProcessorCore - Copy/Colors/Colorspaces/Bgra32.cs
deleted file mode 100644
index cc4fad541e..0000000000
--- a/src/ImageProcessorCore - Copy/Colors/Colorspaces/Bgra32.cs
+++ /dev/null
@@ -1,168 +0,0 @@
-////
-//// Copyright (c) James Jackson-South and contributors.
-//// Licensed under the Apache License, Version 2.0.
-////
-
-//namespace ImageProcessorCore
-//{
-// using System;
-// using System.ComponentModel;
-// using System.Numerics;
-
-// ///
-// /// Represents an BGRA (blue, green, red, alpha) color.
-// ///
-// public struct Bgra32 : IEquatable
-// {
-// ///
-// /// Represents a 32 bit that has B, G, R, and A values set to zero.
-// ///
-// public static readonly Bgra32 Empty = default(Bgra32);
-
-// ///
-// /// The backing vector for SIMD support.
-// ///
-// private Vector4 backingVector;
-
-// ///
-// /// Initializes a new instance of the struct.
-// ///
-// /// The blue component of this .
-// /// The green component of this .
-// /// The red component of this .
-// /// The alpha component of this .
-// public Bgra32(byte b, byte g, byte r, byte a = 255)
-// : this()
-// {
-// this.backingVector = Vector4.Clamp(new Vector4(b, g, r, a), Vector4.Zero, new Vector4(255));
-// }
-
-// ///
-// /// Gets the blue component of the color
-// ///
-// public byte B => (byte)this.backingVector.X;
-
-// ///
-// /// Gets the green component of the color
-// ///
-// public byte G => (byte)this.backingVector.Y;
-
-// ///
-// /// Gets the red component of the color
-// ///
-// public byte R => (byte)this.backingVector.Z;
-
-// ///
-// /// Gets the alpha component of the color
-// ///
-// public byte A => (byte)this.backingVector.W;
-
-// ///
-// /// Gets the integer representation of the color.
-// ///
-// public int Bgra => (this.R << 16) | (this.G << 8) | (this.B << 0) | (this.A << 24);
-
-// ///
-// /// Gets a value indicating whether this is empty.
-// ///
-// [EditorBrowsable(EditorBrowsableState.Never)]
-// public bool IsEmpty => this.Equals(Empty);
-
-// ///
-// /// Allows the implicit conversion of an instance of to a
-// /// .
-// ///
-// ///
-// /// The instance of to convert.
-// ///
-// ///
-// /// An instance of .
-// ///
-// public static implicit operator Bgra32(Color color)
-// {
-// color = color.Limited * 255f;
-// return new Bgra32((byte)color.B, (byte)color.G, (byte)color.R, (byte)color.A);
-// }
-
-// ///
-// /// 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 ==(Bgra32 left, Bgra32 right)
-// {
-// return left.Equals(right);
-// }
-
-// ///
-// /// Compares two objects for inequality.
-// ///
-// ///
-// /// The on the left side of the operand.
-// ///
-// ///
-// /// The on the right side of the operand.
-// ///
-// ///
-// /// True if the current left is unequal to the parameter; otherwise, false.
-// ///
-// public static bool operator !=(Bgra32 left, Bgra32 right)
-// {
-// return !left.Equals(right);
-// }
-
-// ///
-// public override bool Equals(object obj)
-// {
-// if (obj is Bgra32)
-// {
-// Bgra32 color = (Bgra32)obj;
-
-// return this.backingVector == color.backingVector;
-// }
-
-// return false;
-// }
-
-// ///
-// public override int GetHashCode()
-// {
-// return GetHashCode(this);
-// }
-
-// ///
-// public override string ToString()
-// {
-// if (this.IsEmpty)
-// {
-// return "Bgra32 [ Empty ]";
-// }
-
-// return $"Bgra32 [ B={this.B}, G={this.G}, R={this.R}, A={this.A} ]";
-// }
-
-// ///
-// public bool Equals(Bgra32 other)
-// {
-// return this.backingVector.Equals(other.backingVector);
-// }
-
-// ///
-// /// 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 static int GetHashCode(Bgra32 color) => color.backingVector.GetHashCode();
-// }
-//}
diff --git a/src/ImageProcessorCore - Copy/Colors/Colorspaces/CieLab.cs b/src/ImageProcessorCore - Copy/Colors/Colorspaces/CieLab.cs
deleted file mode 100644
index cce92601ad..0000000000
--- a/src/ImageProcessorCore - Copy/Colors/Colorspaces/CieLab.cs
+++ /dev/null
@@ -1,193 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.ComponentModel;
- using System.Numerics;
-
- ///
- /// Represents an CIE LAB 1976 color.
- ///
- ///
- public struct CieLab : IEquatable, IAlmostEquatable
- {
- ///
- /// Represents a that has L, A, B values set to zero.
- ///
- public static readonly CieLab Empty = default(CieLab);
-
- ///
- /// The epsilon for comparing floating point numbers.
- ///
- private const float Epsilon = 0.001f;
-
- ///
- /// The backing vector for SIMD support.
- ///
- private Vector3 backingVector;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The lightness dimension.
- /// The a (green - magenta) component.
- /// The b (blue - yellow) component.
- public CieLab(float l, float a, float b)
- : this()
- {
- this.backingVector = Vector3.Clamp(new Vector3(l, a, b), new Vector3(0, -100, -100), new Vector3(100));
- }
-
- ///
- /// Gets the lightness dimension.
- /// A value ranging between 0 (black), 100 (diffuse white) or higher (specular white).
- ///
- public float L => this.backingVector.X;
-
- ///
- /// Gets the a color component.
- /// Negative is green, positive magenta.
- ///
- public float A => this.backingVector.Y;
-
- ///
- /// Gets the b color component.
- /// Negative is blue, positive is yellow
- ///
- public float B => this.backingVector.Z;
-
- ///
- /// Gets a value indicating whether this is empty.
- ///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public bool IsEmpty => this.Equals(Empty);
-
- ///
- /// Allows the implicit conversion of an instance of to a
- /// .
- ///
- ///
- /// The instance of to convert.
- ///
- ///
- /// An instance of .
- ///
- public static implicit operator CieLab(Color color)
- {
- // First convert to CIE XYZ
- color = Color.Expand(color);
-
- float x = (color.R * 0.4124F) + (color.G * 0.3576F) + (color.B * 0.1805F);
- float y = (color.R * 0.2126F) + (color.G * 0.7152F) + (color.B * 0.0722F);
- float z = (color.R * 0.0193F) + (color.G * 0.1192F) + (color.B * 0.9505F);
-
- // Now to LAB
- x /= 0.95047F;
- //y /= 1F;
- z /= 1.08883F;
-
- x = x > 0.008856F ? (float)Math.Pow(x, 0.3333333F) : (903.3F * x + 16F) / 116F;
- y = y > 0.008856F ? (float)Math.Pow(y, 0.3333333F) : (903.3F * y + 16F) / 116F;
- z = z > 0.008856F ? (float)Math.Pow(z, 0.3333333F) : (903.3F * z + 16F) / 116F;
-
- float l = Math.Max(0, (116F * y) - 16F);
- float a = 500F * (x - y);
- float b = 200F * (y - z);
-
- return new CieLab(l, a, b);
- }
-
- ///
- /// 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 ==(CieLab left, CieLab right)
- {
- return left.Equals(right);
- }
-
- ///
- /// Compares two objects for inequality
- ///
- ///
- /// The on the left side of the operand.
- ///
- ///
- /// The on the right side of the operand.
- ///
- ///
- /// True if the current left is unequal to the parameter; otherwise, false.
- ///
- public static bool operator !=(CieLab left, CieLab right)
- {
- return !left.Equals(right);
- }
-
- ///
- public override int GetHashCode()
- {
- return GetHashCode(this);
- }
-
- ///
- public override string ToString()
- {
- if (this.IsEmpty)
- {
- return "CieLab [Empty]";
- }
-
- return $"CieLab [ L={this.L:#0.##}, A={this.A:#0.##}, B={this.B:#0.##}]";
- }
-
- ///
- public override bool Equals(object obj)
- {
- if (obj is CieLab)
- {
- return this.Equals((CieLab)obj);
- }
-
- return false;
- }
-
- ///
- public bool Equals(CieLab other)
- {
- return this.AlmostEquals(other, Epsilon);
- }
-
- ///
- public bool AlmostEquals(CieLab other, float precision)
- {
- Vector3 result = Vector3.Abs(this.backingVector - other.backingVector);
-
- return result.X < precision
- && result.Y < precision
- && result.Z < precision;
- }
-
- ///
- /// 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 static int GetHashCode(CieLab color) => color.backingVector.GetHashCode();
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Colors/Colorspaces/CieXyz.cs b/src/ImageProcessorCore - Copy/Colors/Colorspaces/CieXyz.cs
deleted file mode 100644
index 8f41c8abbe..0000000000
--- a/src/ImageProcessorCore - Copy/Colors/Colorspaces/CieXyz.cs
+++ /dev/null
@@ -1,184 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.ComponentModel;
- using System.Numerics;
-
- ///
- /// Represents an CIE 1931 color
- ///
- ///
- public struct CieXyz : IEquatable, IAlmostEquatable
- {
- ///
- /// Represents a that has Y, Cb, and Cr values set to zero.
- ///
- public static readonly CieXyz Empty = default(CieXyz);
-
- ///
- /// The epsilon for comparing floating point numbers.
- ///
- private const float Epsilon = 0.001f;
-
- ///
- /// The backing vector for SIMD support.
- ///
- private Vector3 backingVector;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The y luminance component.
- /// X is a mix (a linear combination) of cone response curves chosen to be nonnegative
- /// Z is quasi-equal to blue stimulation, or the S cone of the human eye.
- public CieXyz(float x, float y, float z)
- : this()
- {
- // Not clamping as documentation about this space seems to indicate "usual" ranges
- this.backingVector = new Vector3(x, y, z);
- }
-
- ///
- /// Gets the Y luminance component.
- /// A value ranging between 380 and 780.
- ///
- public float X => this.backingVector.X;
-
- ///
- /// Gets the Cb chroma component.
- /// A value ranging between 380 and 780.
- ///
- public float Y => this.backingVector.Y;
-
- ///
- /// Gets the Cr chroma component.
- /// A value ranging between 380 and 780.
- ///
- public float Z => this.backingVector.Z;
-
- ///
- /// Gets a value indicating whether this is empty.
- ///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public bool IsEmpty => this.Equals(Empty);
-
- ///
- /// Allows the implicit conversion of an instance of to a
- /// .
- ///
- ///
- /// The instance of to convert.
- ///
- ///
- /// An instance of .
- ///
- public static implicit operator CieXyz(Color color)
- {
- color = Color.Expand(color);
-
- float x = (color.R * 0.4124F) + (color.G * 0.3576F) + (color.B * 0.1805F);
- float y = (color.R * 0.2126F) + (color.G * 0.7152F) + (color.B * 0.0722F);
- float z = (color.R * 0.0193F) + (color.G * 0.1192F) + (color.B * 0.9505F);
-
- x *= 100F;
- y *= 100F;
- z *= 100F;
-
- return new CieXyz(x, y, z);
- }
-
- ///
- /// 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 ==(CieXyz left, CieXyz right)
- {
- return left.Equals(right);
- }
-
- ///
- /// Compares two objects for inequality.
- ///
- ///
- /// The on the left side of the operand.
- ///
- ///
- /// The on the right side of the operand.
- ///
- ///
- /// True if the current left is unequal to the parameter; otherwise, false.
- ///
- public static bool operator !=(CieXyz left, CieXyz right)
- {
- return !left.Equals(right);
- }
-
- ///
- public override int GetHashCode()
- {
- return GetHashCode(this);
- }
-
- ///
- public override string ToString()
- {
- if (this.IsEmpty)
- {
- return "CieXyz [ Empty ]";
- }
-
- return $"CieXyz [ X={this.X:#0.##}, Y={this.Y:#0.##}, Z={this.Z:#0.##} ]";
- }
-
- ///
- public override bool Equals(object obj)
- {
- if (obj is CieXyz)
- {
- return this.Equals((CieXyz)obj);
- }
-
- return false;
- }
-
- ///
- public bool Equals(CieXyz other)
- {
- return this.AlmostEquals(other, Epsilon);
- }
-
- ///
- public bool AlmostEquals(CieXyz other, float precision)
- {
- Vector3 result = Vector3.Abs(this.backingVector - other.backingVector);
-
- return result.X < precision
- && result.Y < precision
- && result.Z < precision;
- }
-
- ///
- /// 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 static int GetHashCode(CieXyz color) => color.backingVector.GetHashCode();
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Colors/Colorspaces/Cmyk.cs b/src/ImageProcessorCore - Copy/Colors/Colorspaces/Cmyk.cs
deleted file mode 100644
index b343288a68..0000000000
--- a/src/ImageProcessorCore - Copy/Colors/Colorspaces/Cmyk.cs
+++ /dev/null
@@ -1,197 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.ComponentModel;
- using System.Numerics;
-
- ///
- /// Represents an CMYK (cyan, magenta, yellow, keyline) color.
- ///
- public struct Cmyk : IEquatable, IAlmostEquatable
- {
- ///
- /// Represents a that has C, M, Y, and K values set to zero.
- ///
- public static readonly Cmyk Empty = default(Cmyk);
-
- ///
- /// The epsilon for comparing floating point numbers.
- ///
- private const float Epsilon = 0.001f;
-
- ///
- /// The backing vector for SIMD support.
- ///
- private Vector4 backingVector;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The cyan component.
- /// The magenta component.
- /// The yellow component.
- /// The keyline black component.
- public Cmyk(float c, float m, float y, float k)
- : this()
- {
- this.backingVector = Vector4.Clamp(new Vector4(c, m, y, k), Vector4.Zero, Vector4.One);
- }
-
- ///
- /// Gets the cyan color component.
- /// A value ranging between 0 and 1.
- ///
- public float C => this.backingVector.X;
-
- ///
- /// Gets the magenta color component.
- /// A value ranging between 0 and 1.
- ///
- public float M => this.backingVector.Y;
-
- ///
- /// Gets the yellow color component.
- /// A value ranging between 0 and 1.
- ///
- public float Y => this.backingVector.Z;
-
- ///
- /// Gets the keyline black color component.
- /// A value ranging between 0 and 1.
- ///
- public float K => this.backingVector.W;
-
- ///
- /// Gets a value indicating whether this is empty.
- ///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public bool IsEmpty => this.Equals(Empty);
-
- ///
- /// Allows the implicit conversion of an instance of to a
- /// .
- ///
- ///
- /// The instance of to convert.
- ///
- ///
- /// An instance of .
- ///
- public static implicit operator Cmyk(Color color)
- {
- color = color.Limited;
-
- float c = 1f - color.R;
- float m = 1f - color.G;
- float y = 1f - color.B;
-
- float k = Math.Min(c, Math.Min(m, y));
-
- if (Math.Abs(k - 1.0f) <= Epsilon)
- {
- return new Cmyk(0, 0, 0, 1);
- }
-
- c = (c - k) / (1 - k);
- m = (m - k) / (1 - k);
- y = (y - k) / (1 - k);
-
- return new Cmyk(c, m, y, k);
- }
-
- ///
- /// 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 ==(Cmyk left, Cmyk right)
- {
- return left.Equals(right);
- }
-
- ///
- /// Compares two objects for inequality
- ///
- ///
- /// The on the left side of the operand.
- ///
- ///
- /// The on the right side of the operand.
- ///
- ///
- /// True if the current left is unequal to the parameter; otherwise, false.
- ///
- public static bool operator !=(Cmyk left, Cmyk right)
- {
- return !left.Equals(right);
- }
-
- ///
- public override int GetHashCode()
- {
- return GetHashCode(this);
- }
-
- ///
- public override string ToString()
- {
- if (this.IsEmpty)
- {
- return "Cmyk [Empty]";
- }
-
- return $"Cmyk [ C={this.C:#0.##}, M={this.M:#0.##}, Y={this.Y:#0.##}, K={this.K:#0.##}]";
- }
-
- ///
- public override bool Equals(object obj)
- {
- if (obj is Cmyk)
- {
- return this.Equals((Cmyk)obj);
- }
-
- return false;
- }
-
- ///
- public bool Equals(Cmyk other)
- {
- return this.AlmostEquals(other, Epsilon);
- }
-
- ///
- public bool AlmostEquals(Cmyk other, float precision)
- {
- Vector4 result = Vector4.Abs(this.backingVector - other.backingVector);
-
- return result.X < precision
- && result.Y < precision
- && result.Z < precision
- && result.W < precision;
- }
-
- ///
- /// 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 static int GetHashCode(Cmyk color) => color.backingVector.GetHashCode();
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Colors/Colorspaces/Hsl.cs b/src/ImageProcessorCore - Copy/Colors/Colorspaces/Hsl.cs
deleted file mode 100644
index e6eee42e35..0000000000
--- a/src/ImageProcessorCore - Copy/Colors/Colorspaces/Hsl.cs
+++ /dev/null
@@ -1,213 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.ComponentModel;
- using System.Numerics;
-
- ///
- /// Represents a Hsl (hue, saturation, lightness) color.
- ///
- public struct Hsl : IEquatable, IAlmostEquatable
- {
- ///
- /// Represents a that has H, S, and L values set to zero.
- ///
- public static readonly Hsl Empty = default(Hsl);
-
- ///
- /// The epsilon for comparing floating point numbers.
- ///
- private const float Epsilon = 0.001f;
-
- ///
- /// The backing vector for SIMD support.
- ///
- private Vector3 backingVector;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The h hue component.
- /// The s saturation component.
- /// The l value (lightness) component.
- public Hsl(float h, float s, float l)
- {
- this.backingVector = Vector3.Clamp(new Vector3(h, s, l), Vector3.Zero, new Vector3(360, 1, 1));
- }
-
- ///
- /// Gets the hue component.
- /// A value ranging between 0 and 360.
- ///
- public float H => this.backingVector.X;
-
- ///
- /// Gets the saturation component.
- /// A value ranging between 0 and 1.
- ///
- public float S => this.backingVector.Y;
-
- ///
- /// Gets the lightness component.
- /// A value ranging between 0 and 1.
- ///
- public float L => this.backingVector.Z;
-
- ///
- /// Gets a value indicating whether this is empty.
- ///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public bool IsEmpty => this.Equals(Empty);
-
- ///
- /// Allows the implicit conversion of an instance of to a
- /// .
- ///
- /// The instance of to convert.
- ///
- /// An instance of .
- ///
- public static implicit operator Hsl(Color color)
- {
- color = Color.ToNonPremultiplied(color.Limited);
- float r = color.R;
- float g = color.G;
- float b = color.B;
-
- float max = Math.Max(r, Math.Max(g, b));
- float min = Math.Min(r, Math.Min(g, b));
- float chroma = max - min;
- float h = 0;
- float s = 0;
- float l = (max + min) / 2;
-
- if (Math.Abs(chroma) < Epsilon)
- {
- return new Hsl(0, s, l);
- }
-
- if (Math.Abs(r - max) < Epsilon)
- {
- h = (g - b) / chroma;
- }
- else if (Math.Abs(g - max) < Epsilon)
- {
- h = 2 + ((b - r) / chroma);
- }
- else if (Math.Abs(b - max) < Epsilon)
- {
- h = 4 + ((r - g) / chroma);
- }
-
- h *= 60;
- if (h < 0.0)
- {
- h += 360;
- }
-
- if (l <= .5f)
- {
- s = chroma / (max + min);
- }
- else {
- s = chroma / (2 - chroma);
- }
-
- return new Hsl(h, s, l);
- }
-
- ///
- /// 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 ==(Hsl left, Hsl right)
- {
- return left.Equals(right);
- }
-
- ///
- /// Compares two objects for inequality.
- ///
- ///
- /// The on the left side of the operand.
- ///
- ///
- /// The on the right side of the operand.
- ///
- ///
- /// True if the current left is unequal to the parameter; otherwise, false.
- ///
- public static bool operator !=(Hsl left, Hsl right)
- {
- return !left.Equals(right);
- }
-
- ///
- public override int GetHashCode()
- {
- return GetHashCode(this);
- }
-
- ///
- public override string ToString()
- {
- if (this.IsEmpty)
- {
- return "Hsl [ Empty ]";
- }
-
- return $"Hsl [ H={this.H:#0.##}, S={this.S:#0.##}, L={this.L:#0.##} ]";
- }
-
- ///
- public override bool Equals(object obj)
- {
- if (obj is Hsl)
- {
- return this.Equals((Hsl)obj);
- }
-
- return false;
- }
-
- ///
- public bool Equals(Hsl other)
- {
- return this.AlmostEquals(other, Epsilon);
- }
-
- ///
- public bool AlmostEquals(Hsl other, float precision)
- {
- Vector3 result = Vector3.Abs(this.backingVector - other.backingVector);
-
- return result.X < precision
- && result.Y < precision
- && result.Z < precision;
- }
-
- ///
- /// 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 static int GetHashCode(Hsl color) => color.backingVector.GetHashCode();
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Colors/Colorspaces/Hsv.cs b/src/ImageProcessorCore - Copy/Colors/Colorspaces/Hsv.cs
deleted file mode 100644
index 914df51c97..0000000000
--- a/src/ImageProcessorCore - Copy/Colors/Colorspaces/Hsv.cs
+++ /dev/null
@@ -1,207 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.ComponentModel;
- using System.Numerics;
-
- ///
- /// Represents a HSV (hue, saturation, value) color. Also known as HSB (hue, saturation, brightness).
- ///
- public struct Hsv : IEquatable, IAlmostEquatable
- {
- ///
- /// Represents a that has H, S, and V values set to zero.
- ///
- public static readonly Hsv Empty = default(Hsv);
-
- ///
- /// The epsilon for comparing floating point numbers.
- ///
- private const float Epsilon = 0.001f;
-
- ///
- /// The backing vector for SIMD support.
- ///
- private Vector3 backingVector;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The h hue component.
- /// The s saturation component.
- /// The v value (brightness) component.
- public Hsv(float h, float s, float v)
- {
- this.backingVector = Vector3.Clamp(new Vector3(h, s, v), Vector3.Zero, new Vector3(360, 1, 1));
- }
-
- ///
- /// Gets the hue component.
- /// A value ranging between 0 and 360.
- ///
- public float H => this.backingVector.X;
-
- ///
- /// Gets the saturation component.
- /// A value ranging between 0 and 1.
- ///
- public float S => this.backingVector.Y;
-
- ///
- /// Gets the value (brightness) component.
- /// A value ranging between 0 and 1.
- ///
- public float V => this.backingVector.Z;
-
- ///
- /// Gets a value indicating whether this is empty.
- ///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public bool IsEmpty => this.Equals(Empty);
-
- ///
- /// Allows the implicit conversion of an instance of to a
- /// .
- ///
- /// The instance of to convert.
- ///
- /// An instance of .
- ///
- public static implicit operator Hsv(Color color)
- {
- color = Color.ToNonPremultiplied(color.Limited);
- float r = color.R;
- float g = color.G;
- float b = color.B;
-
- float max = Math.Max(r, Math.Max(g, b));
- float min = Math.Min(r, Math.Min(g, b));
- float chroma = max - min;
- float h = 0;
- float s = 0;
- float v = max;
-
- if (Math.Abs(chroma) < Epsilon)
- {
- return new Hsv(0, s, v);
- }
-
- if (Math.Abs(r - max) < Epsilon)
- {
- h = (g - b) / chroma;
- }
- else if (Math.Abs(g - max) < Epsilon)
- {
- h = 2 + ((b - r) / chroma);
- }
- else if (Math.Abs(b - max) < Epsilon)
- {
- h = 4 + ((r - g) / chroma);
- }
-
- h *= 60;
- if (h < 0.0)
- {
- h += 360;
- }
-
- s = chroma / v;
-
- return new Hsv(h, s, v);
- }
-
- ///
- /// 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 ==(Hsv left, Hsv right)
- {
- return left.Equals(right);
- }
-
- ///
- /// Compares two objects for inequality.
- ///
- ///
- /// The on the left side of the operand.
- ///
- ///
- /// The on the right side of the operand.
- ///
- ///
- /// True if the current left is unequal to the parameter; otherwise, false.
- ///
- public static bool operator !=(Hsv left, Hsv right)
- {
- return !left.Equals(right);
- }
-
- ///
- public override int GetHashCode()
- {
- return GetHashCode(this);
- }
-
- ///
- public override string ToString()
- {
- if (this.IsEmpty)
- {
- return "Hsv [ Empty ]";
- }
-
- return $"Hsv [ H={this.H:#0.##}, S={this.S:#0.##}, V={this.V:#0.##} ]";
- }
-
- ///
- public override bool Equals(object obj)
- {
- if (obj is Hsv)
- {
- return this.Equals((Hsv)obj);
- }
-
- return false;
- }
-
- ///
- public bool Equals(Hsv other)
- {
- return this.AlmostEquals(other, Epsilon);
- }
-
- ///
- public bool AlmostEquals(Hsv other, float precision)
- {
- Vector3 result = Vector3.Abs(this.backingVector - other.backingVector);
-
- return result.X < precision
- && result.Y < precision
- && result.Z < precision;
- }
-
- ///
- /// 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 static int GetHashCode(Hsv color) => color.backingVector.GetHashCode();
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Colors/Colorspaces/YCbCr.cs b/src/ImageProcessorCore - Copy/Colors/Colorspaces/YCbCr.cs
deleted file mode 100644
index 5c47c6c087..0000000000
--- a/src/ImageProcessorCore - Copy/Colors/Colorspaces/YCbCr.cs
+++ /dev/null
@@ -1,183 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.ComponentModel;
- using System.Numerics;
-
- ///
- /// Represents an YCbCr (luminance, chroma, chroma) color conforming to the
- /// Full range standard used in digital imaging systems.
- ///
- ///
- public struct YCbCr : IEquatable, IAlmostEquatable
- {
- ///
- /// Represents a that has Y, Cb, and Cr values set to zero.
- ///
- public static readonly YCbCr Empty = default(YCbCr);
-
- ///
- /// The epsilon for comparing floating point numbers.
- ///
- private const float Epsilon = 0.001f;
-
- ///
- /// The backing vector for SIMD support.
- ///
- private Vector3 backingVector;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The y luminance component.
- /// The cb chroma component.
- /// The cr chroma component.
- public YCbCr(float y, float cb, float cr)
- : this()
- {
- this.backingVector = Vector3.Clamp(new Vector3(y, cb, cr), Vector3.Zero, new Vector3(255));
- }
-
- ///
- /// Gets the Y luminance component.
- /// A value ranging between 0 and 255.
- ///
- public float Y => this.backingVector.X;
-
- ///
- /// Gets the Cb chroma component.
- /// A value ranging between 0 and 255.
- ///
- public float Cb => this.backingVector.Y;
-
- ///
- /// Gets the Cr chroma component.
- /// A value ranging between 0 and 255.
- ///
- public float Cr => this.backingVector.Z;
-
- ///
- /// Gets a value indicating whether this is empty.
- ///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public bool IsEmpty => this.Equals(Empty);
-
- ///
- /// Allows the implicit conversion of an instance of to a
- /// .
- ///
- ///
- /// The instance of to convert.
- ///
- ///
- /// An instance of .
- ///
- public static implicit operator YCbCr(Color color)
- {
- color = Color.ToNonPremultiplied(color.Limited) * 255f;
- float r = color.R;
- float g = color.G;
- float b = color.B;
-
- float y = (float)((0.299 * r) + (0.587 * g) + (0.114 * b));
- float cb = 128 + (float)((-0.168736 * r) - (0.331264 * g) + (0.5 * b));
- float cr = 128 + (float)((0.5 * r) - (0.418688 * g) - (0.081312 * b));
-
- return new YCbCr(y, cb, cr);
- }
-
- ///
- /// 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 ==(YCbCr left, YCbCr right)
- {
- return left.Equals(right);
- }
-
- ///
- /// Compares two objects for inequality.
- ///
- ///
- /// The on the left side of the operand.
- ///
- ///
- /// The on the right side of the operand.
- ///
- ///
- /// True if the current left is unequal to the parameter; otherwise, false.
- ///
- public static bool operator !=(YCbCr left, YCbCr right)
- {
- return !left.Equals(right);
- }
-
- ///
- public override int GetHashCode()
- {
- return GetHashCode(this);
- }
-
- ///
- public override string ToString()
- {
- if (this.IsEmpty)
- {
- return "YCbCr [ Empty ]";
- }
-
- return $"YCbCr [ Y={this.Y:#0.##}, Cb={this.Cb:#0.##}, Cr={this.Cr:#0.##} ]";
- }
-
- ///
- public override bool Equals(object obj)
- {
- if (obj is YCbCr)
- {
- return this.Equals((YCbCr)obj);
- }
-
- return false;
- }
-
- ///
- public bool Equals(YCbCr other)
- {
- return this.AlmostEquals(other, Epsilon);
- }
-
- ///
- public bool AlmostEquals(YCbCr other, float precision)
- {
- Vector3 result = Vector3.Abs(this.backingVector - other.backingVector);
-
- return result.X < precision
- && result.Y < precision
- && result.Z < precision;
- }
-
- ///
- /// 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 static int GetHashCode(YCbCr color) => color.backingVector.GetHashCode();
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Colors/IAlmostEquatable.cs b/src/ImageProcessorCore - Copy/Colors/IAlmostEquatable.cs
deleted file mode 100644
index 4677c3415f..0000000000
--- a/src/ImageProcessorCore - Copy/Colors/IAlmostEquatable.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
-
- ///
- /// Defines a generalized method that a value type or class implements to create
- /// a type-specific method for determining approximate equality of instances.
- ///
- /// The type of objects to compare.
- /// The object specifying the type to specify precision with.
- public interface IAlmostEquatable where TP : struct, IComparable
- {
- ///
- /// Indicates whether the current object is equal to another object of the same type
- /// when compared to the specified precision level.
- ///
- /// An object to compare with this object.
- /// The object specifying the level of precision.
- ///
- /// true if the current object is equal to the other parameter; otherwise, false.
- ///
- bool AlmostEquals(T other, TP precision);
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Colors/RgbaComponent.cs b/src/ImageProcessorCore - Copy/Colors/RgbaComponent.cs
deleted file mode 100644
index a4b668cb62..0000000000
--- a/src/ImageProcessorCore - Copy/Colors/RgbaComponent.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// Enumerates the RGBA (red, green, blue, alpha) color components.
- ///
- public enum RgbaComponent
- {
- ///
- /// The blue component.
- ///
- B = 0,
-
- ///
- /// The green component.
- ///
- G = 1,
-
- ///
- /// The red component.
- ///
- R = 2,
-
- ///
- /// The alpha component.
- ///
- A = 3
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Common/Exceptions/ImageFormatException.cs b/src/ImageProcessorCore - Copy/Common/Exceptions/ImageFormatException.cs
deleted file mode 100644
index 87fb381597..0000000000
--- a/src/ImageProcessorCore - Copy/Common/Exceptions/ImageFormatException.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
-
- ///
- /// The exception that is thrown when the library tries to load
- /// an image, which has an invalid format.
- ///
- public class ImageFormatException : Exception
- {
- ///
- /// Initializes a new instance of the class.
- ///
- public ImageFormatException()
- {
- }
-
- ///
- /// Initializes a new instance of the class with the name of the
- /// parameter that causes this exception.
- ///
- /// The error message that explains the reason for this exception.
- public ImageFormatException(string errorMessage)
- : base(errorMessage)
- {
- }
-
- ///
- /// Initializes a new instance of the class with a specified
- /// error message and the exception that is the cause of this exception.
- ///
- /// The error message that explains the reason for this exception.
- /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic)
- /// if no inner exception is specified.
- public ImageFormatException(string errorMessage, Exception innerException)
- : base(errorMessage, innerException)
- {
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Common/Exceptions/ImageProcessingException.cs b/src/ImageProcessorCore - Copy/Common/Exceptions/ImageProcessingException.cs
deleted file mode 100644
index 7899dcf44c..0000000000
--- a/src/ImageProcessorCore - Copy/Common/Exceptions/ImageProcessingException.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
-
- ///
- /// The exception that is thrown when an error occurs when applying a process to an image.
- ///
- public class ImageProcessingException : Exception
- {
- ///
- /// Initializes a new instance of the class.
- ///
- public ImageProcessingException()
- {
- }
-
- ///
- /// Initializes a new instance of the class with the name of the
- /// parameter that causes this exception.
- ///
- /// The error message that explains the reason for this exception.
- public ImageProcessingException(string errorMessage)
- : base(errorMessage)
- {
- }
-
- ///
- /// Initializes a new instance of the class with a specified
- /// error message and the exception that is the cause of this exception.
- ///
- /// The error message that explains the reason for this exception.
- /// The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic)
- /// if no inner exception is specified.
- public ImageProcessingException(string errorMessage, Exception innerException)
- : base(errorMessage, innerException)
- {
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Common/Extensions/ByteExtensions.cs b/src/ImageProcessorCore - Copy/Common/Extensions/ByteExtensions.cs
deleted file mode 100644
index 05b71bb2f6..0000000000
--- a/src/ImageProcessorCore - Copy/Common/Extensions/ByteExtensions.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
-
- ///
- /// Extension methods for the struct.
- ///
- internal static class ByteExtensions
- {
- ///
- /// Converts a byte array to a new array where each value in the original array is represented
- /// by a the specified number of bits.
- ///
- /// The bytes to convert from. Cannot be null.
- /// The number of bits per value.
- /// The resulting array. Is never null.
- /// is null.
- /// is less than or equals than zero.
- public static byte[] ToArrayByBitsLength(this byte[] bytes, int bits)
- {
- Guard.NotNull(bytes, "bytes");
- Guard.MustBeGreaterThan(bits, 0, "bits");
-
- byte[] result;
-
- if (bits < 8)
- {
- result = new byte[bytes.Length * 8 / bits];
-
- // BUGFIX I dont think it should be there, but I am not sure if it breaks something else
- // int factor = (int)Math.Pow(2, bits) - 1;
- int mask = 0xFF >> (8 - bits);
- int resultOffset = 0;
-
- foreach (byte b in bytes)
- {
- for (int shift = 0; shift < 8; shift += bits)
- {
- int colorIndex = (b >> (8 - bits - shift)) & mask; // * (255 / factor);
-
- result[resultOffset] = (byte)colorIndex;
-
- resultOffset++;
- }
- }
- }
- else
- {
- result = bytes;
- }
-
- return result;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Common/Extensions/ComparableExtensions.cs b/src/ImageProcessorCore - Copy/Common/Extensions/ComparableExtensions.cs
deleted file mode 100644
index cb0288fb7b..0000000000
--- a/src/ImageProcessorCore - Copy/Common/Extensions/ComparableExtensions.cs
+++ /dev/null
@@ -1,145 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
-
- ///
- /// Extension methods for classes that implement .
- ///
- internal static class ComparableExtensions
- {
- ///
- /// Restricts a to be within a specified range.
- ///
- /// The 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 representing the clamped value.
- ///
- public static byte Clamp(this byte value, byte min, byte max)
- {
- // Order is important here as someone might set min to higher than max.
- if (value > max)
- {
- return max;
- }
-
- if (value < min)
- {
- return min;
- }
-
- return value;
- }
-
- ///
- /// Restricts a to be within a specified range.
- ///
- /// The 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 representing the clamped value.
- ///
- public static int Clamp(this int value, int min, int max)
- {
- if (value > max)
- {
- return max;
- }
-
- if (value < min)
- {
- return min;
- }
-
- return value;
- }
-
- ///
- /// Restricts a to be within a specified range.
- ///
- /// The 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 representing the clamped value.
- ///
- public static float Clamp(this float value, float min, float max)
- {
- if (value > max)
- {
- return max;
- }
-
- if (value < min)
- {
- return min;
- }
-
- return value;
- }
-
- ///
- /// Restricts a to be within a specified range.
- ///
- /// The 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 representing the clamped value.
- ///
- public static double Clamp(this double value, double min, double max)
- {
- if (value > max)
- {
- return max;
- }
-
- if (value < min)
- {
- return min;
- }
-
- return value;
- }
-
- ///
- /// Converts an to a first restricting the value between the
- /// minimum and maximum allowable ranges.
- ///
- /// The this method extends.
- /// The
- public static byte ToByte(this int value)
- {
- return (byte)value.Clamp(0, 255);
- }
-
- ///
- /// Converts an to a first restricting the value between the
- /// minimum and maximum allowable ranges.
- ///
- /// The this method extends.
- /// The
- public static byte ToByte(this float value)
- {
- return (byte)value.Clamp(0, 255);
- }
-
- ///
- /// Converts an to a first restricting the value between the
- /// minimum and maximum allowable ranges.
- ///
- /// The this method extends.
- /// The
- public static byte ToByte(this double value)
- {
- return (byte)value.Clamp(0, 255);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Common/Extensions/EnumerableExtensions.cs b/src/ImageProcessorCore - Copy/Common/Extensions/EnumerableExtensions.cs
deleted file mode 100644
index 107320412e..0000000000
--- a/src/ImageProcessorCore - Copy/Common/Extensions/EnumerableExtensions.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.Collections.Generic;
-
- ///
- /// Encapsulates a series of time saving extension methods to the interface.
- ///
- public static class EnumerableExtensions
- {
- ///
- /// Generates a sequence of integral numbers within a specified range.
- ///
- ///
- /// The start index, inclusive.
- ///
- ///
- /// The end index, exclusive.
- ///
- ///
- /// The incremental step.
- ///
- ///
- /// The that contains a range of sequential integral numbers.
- ///
- public static IEnumerable SteppedRange(int fromInclusive, int toExclusive, int step)
- {
- // Borrowed from Enumerable.Range
- long num = (fromInclusive + toExclusive) - 1L;
- if ((toExclusive < 0) || (num > 0x7fffffffL))
- {
- throw new ArgumentOutOfRangeException(nameof(toExclusive));
- }
-
- return RangeIterator(fromInclusive, i => i < toExclusive, step);
- }
-
- ///
- /// Generates a sequence of integral numbers within a specified range.
- ///
- ///
- /// The start index, inclusive.
- ///
- ///
- /// A method that has one parameter and returns a calculating the end index
- ///
- ///
- /// The incremental step.
- ///
- ///
- /// The that contains a range of sequential integral numbers.
- ///
- public static IEnumerable SteppedRange(int fromInclusive, Func toDelegate, int step)
- {
- return RangeIterator(fromInclusive, toDelegate, step);
- }
-
- ///
- /// Generates a sequence of integral numbers within a specified range.
- ///
- ///
- /// The start index, inclusive.
- ///
- ///
- /// A method that has one parameter and returns a calculating the end index
- ///
- ///
- /// The incremental step.
- ///
- ///
- /// The that contains a range of sequential integral numbers.
- ///
- private static IEnumerable RangeIterator(int fromInclusive, Func toDelegate, int step)
- {
- int i = fromInclusive;
- while (toDelegate(i))
- {
- yield return i;
- i += step;
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/Common/Helpers/Guard.cs b/src/ImageProcessorCore - Copy/Common/Helpers/Guard.cs
deleted file mode 100644
index 96c7023d43..0000000000
--- a/src/ImageProcessorCore - Copy/Common/Helpers/Guard.cs
+++ /dev/null
@@ -1,192 +0,0 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-//
-// Provides methods to protect against invalid parameters.
-//
-// --------------------------------------------------------------------------------------------------------------------
-
-using System.Runtime.CompilerServices;
-
-[assembly: InternalsVisibleTo("ImageProcessorCore.Tests")]
-namespace ImageProcessorCore
-{
- using System;
- using System.Diagnostics;
-
- ///
- /// Provides methods to protect against invalid parameters.
- ///
- [DebuggerStepThrough]
- internal static class Guard
- {
- ///
- /// Verifies, that the method parameter with specified object value is not null
- /// and throws an exception if it is found to be so.
- ///
- ///
- /// The target object, which cannot be null.
- ///
- ///
- /// The name of the parameter that is to be checked.
- ///
- ///
- /// The error message, if any to add to the exception.
- ///
- ///
- /// is null
- ///
- public static void NotNull(object target, string parameterName, string message = "")
- {
- if (target == null)
- {
- if (string.IsNullOrWhiteSpace(message))
- {
- throw new ArgumentNullException(parameterName, message);
- }
-
- throw new ArgumentNullException(parameterName);
- }
- }
-
- ///
- /// Verifies, that the string method parameter with specified object value and message
- /// is not null, not empty and does not contain only blanks and throws an exception
- /// if the object is null.
- ///
- /// The target string, which should be checked against being null or empty.
- /// Name of the parameter.
- ///
- /// is null.
- ///
- ///
- /// is
- /// empty or contains only blanks.
- ///
- public static void NotNullOrEmpty(string target, string parameterName)
- {
- if (target == null)
- {
- throw new ArgumentNullException(parameterName);
- }
-
- if (string.IsNullOrWhiteSpace(target))
- {
- throw new ArgumentException("Value cannot be null or empty and cannot contain only blanks.", parameterName);
- }
- }
-
- ///
- /// Verifies that the specified value is less than a maximum value
- /// and throws an exception if it is not.
- ///
- /// The target value, which should be validated.
- /// The maximum value.
- /// The name of the parameter that is to be checked.
- /// The type of the value.
- ///
- /// is greater than the maximum value.
- ///
- public static void MustBeLessThan(TValue value, TValue max, string parameterName)
- where TValue : IComparable
- {
- if (value.CompareTo(max) >= 0)
- {
- throw new ArgumentOutOfRangeException(
- parameterName,
- $"Value must be less than {max}.");
- }
- }
-
- ///
- /// Verifies that the specified value is less than or equal to a maximum value
- /// and throws an exception if it is not.
- ///
- /// The target value, which should be validated.
- /// The maximum value.
- /// The name of the parameter that is to be checked.
- /// The type of the value.
- ///
- /// is greater than the maximum value.
- ///
- public static void MustBeLessThanOrEqualTo(TValue value, TValue max, string parameterName)
- where TValue : IComparable
- {
- if (value.CompareTo(max) > 0)
- {
- throw new ArgumentOutOfRangeException(
- parameterName,
- $"Value must be less than or equal to {max}.");
- }
- }
-
- ///
- /// Verifies that the specified value is greater than a minimum value
- /// and throws an exception if it is not.
- ///
- /// The target value, which should be validated.
- /// The minimum value.
- /// The name of the parameter that is to be checked.
- /// The type of the value.
- ///
- /// is less than the minimum value.
- ///
- public static void MustBeGreaterThan(TValue value, TValue min, string parameterName)
- where TValue : IComparable
- {
- if (value.CompareTo(min) <= 0)
- {
- throw new ArgumentOutOfRangeException(
- parameterName,
- $"Value must be greater than {min}.");
- }
- }
-
- ///
- /// Verifies that the specified value is greater than or equal to a minimum value
- /// and throws an exception if it is not.
- ///
- /// The target value, which should be validated.
- /// The minimum value.
- /// The name of the parameter that is to be checked.
- /// The type of the value.
- ///
- /// is less than the minimum value.
- ///
- public static void MustBeGreaterThanOrEqualTo(TValue value, TValue min, string parameterName)
- where TValue : IComparable
- {
- if (value.CompareTo(min) < 0)
- {
- throw new ArgumentOutOfRangeException(
- parameterName,
- $"Value must be greater than or equal to {min}.");
- }
- }
-
- ///
- /// Verifies that the specified value is greater than or equal to a minimum value and less than
- /// or equal to a maximum value and throws an exception if it is not.
- ///
- /// The target value, which should be validated.
- /// The minimum value.
- /// The maximum value.
- /// The name of the parameter that is to be checked.
- /// The type of the value.
- ///
- /// is less than the minimum value of greater than the maximum value.
- ///
- public static void MustBeBetweenOrEqualTo(TValue value, TValue min, TValue max, string parameterName)
- where TValue : IComparable
- {
- if (value.CompareTo(min) < 0 || value.CompareTo(max) > 0)
- {
- throw new ArgumentOutOfRangeException(
- parameterName,
- $"Value must be greater than or equal to {min} and less than or equal to {max}.");
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Common/Helpers/ImageMaths.cs b/src/ImageProcessorCore - Copy/Common/Helpers/ImageMaths.cs
deleted file mode 100644
index 051b75f70f..0000000000
--- a/src/ImageProcessorCore - Copy/Common/Helpers/ImageMaths.cs
+++ /dev/null
@@ -1,289 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.Linq;
- using System.Numerics;
-
- ///
- /// Provides common mathematical methods.
- ///
- internal static class ImageMaths
- {
- ///
- /// Returns how many bits are required to store the specified number of colors.
- /// Performs a Log2() on the value.
- ///
- /// The number of colors.
- ///
- /// The
- ///
- public static int GetBitsNeededForColorDepth(int colors)
- {
- return (int)Math.Ceiling(Math.Log(colors, 2));
- }
-
- ///
- /// Implementation of 1D Gaussian G(x) function
- ///
- /// The x provided to G(x).
- /// The spread of the blur.
- /// The Gaussian G(x)
- public static float Gaussian(float x, float sigma)
- {
- const float Numerator = 1.0f;
- float denominator = (float)(Math.Sqrt(2 * Math.PI) * sigma);
-
- float exponentNumerator = -x * x;
- float exponentDenominator = (float)(2 * Math.Pow(sigma, 2));
-
- float left = Numerator / denominator;
- float right = (float)Math.Exp(exponentNumerator / exponentDenominator);
-
- return left * right;
- }
-
- ///
- /// Returns the result of a B-C filter against the given value.
- ///
- ///
- /// The value to process.
- /// The B-Spline curve variable.
- /// The Cardinal curve variable.
- ///
- /// The .
- ///
- public static float GetBcValue(float x, float b, float c)
- {
- float temp;
-
- if (x < 0)
- {
- x = -x;
- }
-
- temp = x * x;
- if (x < 1)
- {
- x = ((12 - (9 * b) - (6 * c)) * (x * temp)) + ((-18 + (12 * b) + (6 * c)) * temp) + (6 - (2 * b));
- return x / 6;
- }
-
- if (x < 2)
- {
- x = ((-b - (6 * c)) * (x * temp)) + (((6 * b) + (30 * c)) * temp) + (((-12 * b) - (48 * c)) * x) + ((8 * b) + (24 * c));
- return x / 6;
- }
-
- return 0;
- }
-
- ///
- /// Gets the result of a sine cardinal function for the given value.
- ///
- /// The value to calculate the result for.
- ///
- /// The .
- ///
- public static float SinC(float x)
- {
- const float Epsilon = .00001f;
-
- if (Math.Abs(x) > Epsilon)
- {
- x *= (float)Math.PI;
- return Clean((float)Math.Sin(x) / x);
- }
-
- return 1.0f;
- }
-
- ///
- /// Returns the given degrees converted to radians.
- ///
- /// The angle in degrees.
- ///
- /// The representing the degree as radians.
- ///
- public static float DegreesToRadians(float degrees)
- {
- return degrees * (float)(Math.PI / 180);
- }
-
- ///
- /// Gets the bounding from the given points.
- ///
- ///
- /// The designating the top left position.
- ///
- ///
- /// The designating the bottom right position.
- ///
- ///
- /// The bounding .
- ///
- public static Rectangle GetBoundingRectangle(Point topLeft, Point bottomRight)
- {
- return new Rectangle(topLeft.X, topLeft.Y, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y);
- }
-
- ///
- /// Gets the bounding from the given matrix.
- ///
- /// The source rectangle.
- /// The transformation matrix.
- ///
- /// The .
- ///
- public static Rectangle GetBoundingRectangle(Rectangle rectangle, Matrix3x2 matrix)
- {
- Vector2 leftTop = Vector2.Transform(new Vector2(rectangle.Left, rectangle.Top), matrix);
- Vector2 rightTop = Vector2.Transform(new Vector2(rectangle.Right, rectangle.Top), matrix);
- Vector2 leftBottom = Vector2.Transform(new Vector2(rectangle.Left, rectangle.Bottom), matrix);
- Vector2 rightBottom = Vector2.Transform(new Vector2(rectangle.Right, rectangle.Bottom), matrix);
-
- Vector2[] allCorners = { leftTop, rightTop, leftBottom, rightBottom };
- float extentX = allCorners.Select(v => v.X).Max() - allCorners.Select(v => v.X).Min();
- float extentY = allCorners.Select(v => v.Y).Max() - allCorners.Select(v => v.Y).Min();
- return new Rectangle(0, 0, (int)extentX, (int)extentY);
- }
-
- ///
- /// Finds the bounding rectangle based on the first instance of any color component other
- /// than the given one.
- ///
- /// The to search within.
- /// The color component value to remove.
- /// The channel to test against.
- ///
- /// The .
- ///
- public static Rectangle GetFilteredBoundingRectangle(ImageBase bitmap, float componentValue, RgbaComponent channel = RgbaComponent.B)
- {
- const float Epsilon = .00001f;
- int width = bitmap.Width;
- int height = bitmap.Height;
- Point topLeft = new Point();
- Point bottomRight = new Point();
-
- Func delegateFunc;
-
- // Determine which channel to check against
- switch (channel)
- {
- case RgbaComponent.R:
- delegateFunc = (pixels, x, y, b) => Math.Abs(pixels[x, y].R - b) > Epsilon;
- break;
-
- case RgbaComponent.G:
- delegateFunc = (pixels, x, y, b) => Math.Abs(pixels[x, y].G - b) > Epsilon;
- break;
-
- case RgbaComponent.A:
- delegateFunc = (pixels, x, y, b) => Math.Abs(pixels[x, y].A - b) > Epsilon;
- break;
-
- default:
- delegateFunc = (pixels, x, y, b) => Math.Abs(pixels[x, y].B - b) > Epsilon;
- break;
- }
-
- Func getMinY = pixels =>
- {
- for (int y = 0; y < height; y++)
- {
- for (int x = 0; x < width; x++)
- {
- if (delegateFunc(pixels, x, y, componentValue))
- {
- return y;
- }
- }
- }
-
- return 0;
- };
-
- Func getMaxY = pixels =>
- {
- for (int y = height - 1; y > -1; y--)
- {
- for (int x = 0; x < width; x++)
- {
- if (delegateFunc(pixels, x, y, componentValue))
- {
- return y;
- }
- }
- }
-
- return height;
- };
-
- Func getMinX = pixels =>
- {
- for (int x = 0; x < width; x++)
- {
- for (int y = 0; y < height; y++)
- {
- if (delegateFunc(pixels, x, y, componentValue))
- {
- return x;
- }
- }
- }
-
- return 0;
- };
-
- Func getMaxX = pixels =>
- {
- for (int x = width - 1; x > -1; x--)
- {
- for (int y = 0; y < height; y++)
- {
- if (delegateFunc(pixels, x, y, componentValue))
- {
- return x;
- }
- }
- }
-
- return height;
- };
-
- using (PixelAccessor bitmapPixels = bitmap.Lock())
- {
- topLeft.Y = getMinY(bitmapPixels);
- topLeft.X = getMinX(bitmapPixels);
- bottomRight.Y = (getMaxY(bitmapPixels) + 1).Clamp(0, height);
- bottomRight.X = (getMaxX(bitmapPixels) + 1).Clamp(0, width);
- }
-
- return GetBoundingRectangle(topLeft, bottomRight);
- }
-
- ///
- /// Ensures that any passed double is correctly rounded to zero
- ///
- /// The value to clean.
- ///
- /// The
- /// .
- private static float Clean(float x)
- {
- const float Epsilon = .00001f;
-
- if (Math.Abs(x) < Epsilon)
- {
- return 0f;
- }
-
- return x;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Alpha.cs b/src/ImageProcessorCore - Copy/Filters/Alpha.cs
deleted file mode 100644
index 3532bb675d..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Alpha.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Alters the alpha component of the image.
- ///
- /// The image this method extends.
- /// The new opacity of the image. Must be between 0 and 100.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Alpha(this Image source, int percent, ProgressEventHandler progressHandler = null)
- {
- return Alpha(source, percent, source.Bounds, progressHandler);
- }
-
- ///
- /// Alters the alpha component of the image.
- ///
- /// The image this method extends.
- /// The new opacity of the image. Must be between 0 and 100.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Alpha(this Image source, int percent, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- AlphaProcessor processor = new AlphaProcessor(percent);
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/BackgroundColor.cs b/src/ImageProcessorCore - Copy/Filters/BackgroundColor.cs
deleted file mode 100644
index 98709cb32c..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/BackgroundColor.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Combines the given image together with the current one by blending their pixels.
- ///
- /// The image this method extends.
- /// The color to set as the background.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image BackgroundColor(this Image source, Color color, ProgressEventHandler progressHandler = null)
- {
- BackgroundColorProcessor processor = new BackgroundColorProcessor(color);
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(source.Bounds, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/BlackWhite.cs b/src/ImageProcessorCore - Copy/Filters/BlackWhite.cs
deleted file mode 100644
index 98c3b7744a..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/BlackWhite.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Applies black and white toning to the image.
- ///
- /// The image this method extends.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image BlackWhite(this Image source, ProgressEventHandler progressHandler = null)
- {
- return BlackWhite(source, source.Bounds, progressHandler);
- }
-
- ///
- /// Applies black and white toning to the image.
- ///
- /// The image this method extends.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image BlackWhite(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- BlackWhiteProcessor processor = new BlackWhiteProcessor();
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Blend.cs b/src/ImageProcessorCore - Copy/Filters/Blend.cs
deleted file mode 100644
index 77a94e3fa3..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Blend.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Combines the given image together with the current one by blending their pixels.
- ///
- /// The image this method extends.
- ///
- /// The image to blend with the currently processing image.
- /// Disposal of this image is the responsibility of the developer.
- ///
- /// The opacity of the image image to blend. Must be between 0 and 100.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Blend(this Image source, ImageBase image, int percent = 50, ProgressEventHandler progressHandler = null)
- {
- return Blend(source, image, percent, source.Bounds, progressHandler);
- }
-
- ///
- /// Combines the given image together with the current one by blending their pixels.
- ///
- /// The image this method extends.
- ///
- /// The image to blend with the currently processing image.
- /// Disposal of this image is the responsibility of the developer.
- ///
- /// The opacity of the image image to blend. Must be between 0 and 100.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Blend(this Image source, ImageBase image, int percent, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- BlendProcessor processor = new BlendProcessor(image, percent);
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/BoxBlur.cs b/src/ImageProcessorCore - Copy/Filters/BoxBlur.cs
deleted file mode 100644
index 474f0d6e77..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/BoxBlur.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Applies a box blur to the image.
- ///
- /// The image this method extends.
- /// The 'radius' value representing the size of the area to sample.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image BoxBlur(this Image source, int radius = 7, ProgressEventHandler progressHandler = null)
- {
- return BoxBlur(source, radius, source.Bounds, progressHandler);
- }
-
- ///
- /// Applies a box blur to the image.
- ///
- /// The image this method extends.
- /// The 'radius' value representing the size of the area to sample.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image BoxBlur(this Image source, int radius, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- BoxBlurProcessor processor = new BoxBlurProcessor(radius);
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Brightness.cs b/src/ImageProcessorCore - Copy/Filters/Brightness.cs
deleted file mode 100644
index 52944c8010..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Brightness.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Alters the brightness component of the image.
- ///
- /// The image this method extends.
- /// The new brightness of the image. Must be between -100 and 100.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Brightness(this Image source, int amount, ProgressEventHandler progressHandler = null)
- {
- return Brightness(source, amount, source.Bounds, progressHandler);
- }
-
- ///
- /// Alters the brightness component of the image.
- ///
- /// The image this method extends.
- /// The new brightness of the image. Must be between -100 and 100.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Brightness(this Image source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- BrightnessProcessor processor = new BrightnessProcessor(amount);
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/ColorBlindness.cs b/src/ImageProcessorCore - Copy/Filters/ColorBlindness.cs
deleted file mode 100644
index 78267b05e3..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/ColorBlindness.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Applies the given colorblindness simulator to the image.
- ///
- /// The image this method extends.
- /// The type of color blindness simulator to apply.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image ColorBlindness(this Image source, ColorBlindness colorBlindness, ProgressEventHandler progressHandler = null)
- {
- return ColorBlindness(source, colorBlindness, source.Bounds, progressHandler);
- }
-
- ///
- /// Applies the given colorblindness simulator to the image.
- ///
- /// The image this method extends.
- /// The type of color blindness simulator to apply.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image ColorBlindness(this Image source, ColorBlindness colorBlindness, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- IImageProcessor processor;
-
- switch (colorBlindness)
- {
- case ImageProcessorCore.ColorBlindness.Achromatomaly:
- processor = new AchromatomalyProcessor();
- break;
-
- case ImageProcessorCore.ColorBlindness.Achromatopsia:
- processor = new AchromatopsiaProcessor();
- break;
-
- case ImageProcessorCore.ColorBlindness.Deuteranomaly:
- processor = new DeuteranomalyProcessor();
- break;
-
- case ImageProcessorCore.ColorBlindness.Deuteranopia:
- processor = new DeuteranopiaProcessor();
- break;
-
- case ImageProcessorCore.ColorBlindness.Protanomaly:
- processor = new ProtanomalyProcessor();
- break;
-
- case ImageProcessorCore.ColorBlindness.Protanopia:
- processor = new ProtanopiaProcessor();
- break;
-
- case ImageProcessorCore.ColorBlindness.Tritanomaly:
- processor = new TritanomalyProcessor();
- break;
-
- default:
- processor = new TritanopiaProcessor();
- break;
- }
-
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Contrast.cs b/src/ImageProcessorCore - Copy/Filters/Contrast.cs
deleted file mode 100644
index cab12ca4e5..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Contrast.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Alters the contrast component of the image.
- ///
- /// The image this method extends.
- /// The new contrast of the image. Must be between -100 and 100.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Contrast(this Image source, int amount, ProgressEventHandler progressHandler = null)
- {
- return Contrast(source, amount, source.Bounds, progressHandler);
- }
-
- ///
- /// Alters the contrast component of the image.
- ///
- /// The image this method extends.
- /// The new contrast of the image. Must be between -100 and 100.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Contrast(this Image source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- ContrastProcessor processor = new ContrastProcessor(amount);
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/DetectEdges.cs b/src/ImageProcessorCore - Copy/Filters/DetectEdges.cs
deleted file mode 100644
index ac3a0282d5..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/DetectEdges.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Detects any edges within the image. Uses the filter
- /// operating in greyscale mode.
- ///
- /// The image this method extends.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image DetectEdges(this Image source, ProgressEventHandler progressHandler = null)
- {
- return DetectEdges(source, source.Bounds, new SobelProcessor { Greyscale = true }, progressHandler);
- }
-
- ///
- /// Detects any edges within the image.
- ///
- /// The image this method extends.
- /// The filter for detecting edges.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image DetectEdges(this Image source, IEdgeDetectorFilter filter, ProgressEventHandler progressHandler = null)
- {
- return DetectEdges(source, source.Bounds, filter, progressHandler);
- }
-
- ///
- /// Detects any edges within the image.
- ///
- /// The image this method extends.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// The filter for detecting edges.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image DetectEdges(this Image source, Rectangle rectangle, IEdgeDetectorFilter filter, ProgressEventHandler progressHandler = null)
- {
- filter.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, filter);
- }
- finally
- {
- filter.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Greyscale.cs b/src/ImageProcessorCore - Copy/Filters/Greyscale.cs
deleted file mode 100644
index 786a935766..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Greyscale.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Applies greyscale toning to the image.
- ///
- /// The image this method extends.
- /// The formula to apply to perform the operation.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Greyscale(this Image source, GreyscaleMode mode = GreyscaleMode.Bt709, ProgressEventHandler progressHandler = null)
- {
- return Greyscale(source, source.Bounds, mode, progressHandler);
- }
-
- ///
- /// Applies greyscale toning to the image.
- ///
- /// The image this method extends.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// The formula to apply to perform the operation.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Greyscale(this Image source, Rectangle rectangle, GreyscaleMode mode = GreyscaleMode.Bt709, ProgressEventHandler progressHandler = null)
- {
- IImageProcessor processor = mode == GreyscaleMode.Bt709
- ? (IImageProcessor)new GreyscaleBt709Processor()
- : new GreyscaleBt601Processor();
-
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/GuassianBlur.cs b/src/ImageProcessorCore - Copy/Filters/GuassianBlur.cs
deleted file mode 100644
index 646c6bdc08..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/GuassianBlur.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Applies a Guassian blur to the image.
- ///
- /// The image this method extends.
- /// The 'sigma' value representing the weight of the blur.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image GuassianBlur(this Image source, float sigma = 3f, ProgressEventHandler progressHandler = null)
- {
- return GuassianBlur(source, sigma, source.Bounds, progressHandler);
- }
-
- ///
- /// Applies a Guassian blur to the image.
- ///
- /// The image this method extends.
- /// The 'sigma' value representing the weight of the blur.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image GuassianBlur(this Image source, float sigma, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- GuassianBlurProcessor processor = new GuassianBlurProcessor(sigma);
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/GuassianSharpen.cs b/src/ImageProcessorCore - Copy/Filters/GuassianSharpen.cs
deleted file mode 100644
index 06993070d8..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/GuassianSharpen.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Applies a Guassian sharpening filter to the image.
- ///
- /// The image this method extends.
- /// The 'sigma' value representing the weight of the blur.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image GuassianSharpen(this Image source, float sigma = 3f, ProgressEventHandler progressHandler = null)
- {
- return GuassianSharpen(source, sigma, source.Bounds, progressHandler);
- }
-
- ///
- /// Applies a Guassian sharpening filter to the image.
- ///
- /// The image this method extends.
- /// The 'sigma' value representing the weight of the blur.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image GuassianSharpen(this Image source, float sigma, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- GuassianSharpenProcessor processor = new GuassianSharpenProcessor(sigma);
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Hue.cs b/src/ImageProcessorCore - Copy/Filters/Hue.cs
deleted file mode 100644
index 45a995c301..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Hue.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Alters the hue component of the image.
- ///
- /// The image this method extends.
- /// The angle in degrees to adjust the image.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Hue(this Image source, float degrees, ProgressEventHandler progressHandler = null)
- {
- return Hue(source, degrees, source.Bounds, progressHandler);
- }
-
- ///
- /// Alters the hue component of the image.
- ///
- /// The image this method extends.
- /// The angle in degrees to adjust the image.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Hue(this Image source, float degrees, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- HueProcessor processor = new HueProcessor(degrees);
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Invert.cs b/src/ImageProcessorCore - Copy/Filters/Invert.cs
deleted file mode 100644
index eaeddfc62b..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Invert.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Inverts the colors of the image.
- ///
- /// The image this method extends.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Invert(this Image source, ProgressEventHandler progressHandler = null)
- {
- return Invert(source, source.Bounds, progressHandler);
- }
-
- ///
- /// Inverts the colors of the image.
- ///
- /// The image this method extends.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Invert(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- InvertProcessor processor = new InvertProcessor();
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Kodachrome.cs b/src/ImageProcessorCore - Copy/Filters/Kodachrome.cs
deleted file mode 100644
index 3b4e3f1c66..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Kodachrome.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Alters the colors of the image recreating an old Kodachrome camera effect.
- ///
- /// The image this method extends.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Kodachrome(this Image source, ProgressEventHandler progressHandler = null)
- {
- return Kodachrome(source, source.Bounds, progressHandler);
- }
-
- ///
- /// Alters the colors of the image recreating an old Kodachrome camera effect.
- ///
- /// The image this method extends.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Kodachrome(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- KodachromeProcessor processor = new KodachromeProcessor();
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Lomograph.cs b/src/ImageProcessorCore - Copy/Filters/Lomograph.cs
deleted file mode 100644
index 5ecf0bcf4a..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Lomograph.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Alters the colors of the image recreating an old Lomograph camera effect.
- ///
- /// The image this method extends.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Lomograph(this Image source, ProgressEventHandler progressHandler = null)
- {
- return Lomograph(source, source.Bounds, progressHandler);
- }
-
- ///
- /// Alters the colors of the image recreating an old Lomograph camera effect.
- ///
- /// The image this method extends.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Lomograph(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- LomographProcessor processor = new LomographProcessor();
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Options/ColorBlindness.cs b/src/ImageProcessorCore - Copy/Filters/Options/ColorBlindness.cs
deleted file mode 100644
index 6d7fe849bc..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Options/ColorBlindness.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// Enumerates the various types of color blindness.
- ///
- public enum ColorBlindness
- {
- ///
- /// Partial color desensitivity.
- ///
- Achromatomaly,
-
- ///
- /// Complete color desensitivity (Monochrome)
- ///
- Achromatopsia,
-
- ///
- /// Green weak
- ///
- Deuteranomaly,
-
- ///
- /// Green blind
- ///
- Deuteranopia,
-
- ///
- /// Red weak
- ///
- Protanomaly,
-
- ///
- /// Red blind
- ///
- Protanopia,
-
- ///
- /// Blue weak
- ///
- Tritanomaly,
-
- ///
- /// Blue blind
- ///
- Tritanopia
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Pixelate.cs b/src/ImageProcessorCore - Copy/Filters/Pixelate.cs
deleted file mode 100644
index 6f86848d6a..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Pixelate.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Pixelates and image with the given pixel size.
- ///
- /// The image this method extends.
- /// The size of the pixels.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Pixelate(this Image source, int size = 4, ProgressEventHandler progressHandler = null)
- {
- return Pixelate(source, size, source.Bounds, progressHandler);
- }
-
- ///
- /// Pixelates and image with the given pixel size.
- ///
- /// The image this method extends.
- /// The size of the pixels.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Pixelate(this Image source, int size, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- PixelateProcessor processor = new PixelateProcessor(size);
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Polaroid.cs b/src/ImageProcessorCore - Copy/Filters/Polaroid.cs
deleted file mode 100644
index 165f1d59a5..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Polaroid.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Alters the colors of the image recreating an old Polaroid camera effect.
- ///
- /// The image this method extends.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Polaroid(this Image source, ProgressEventHandler progressHandler = null)
- {
- return Polaroid(source, source.Bounds, progressHandler);
- }
-
- ///
- /// Alters the colors of the image recreating an old Polaroid camera effect.
- ///
- /// The image this method extends.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Polaroid(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- PolaroidProcessor processor = new PolaroidProcessor();
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/AlphaProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/AlphaProcessor.cs
deleted file mode 100644
index 8ed703e034..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/AlphaProcessor.cs
+++ /dev/null
@@ -1,69 +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;
-
- ///
- /// An to change the Alpha of an .
- ///
- public class AlphaProcessor : ImageProcessor
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The percentage to adjust the opacity of the image. Must be between 0 and 100.
- ///
- /// is less than 0 or is greater than 100.
- ///
- public AlphaProcessor(int percent)
- {
- Guard.MustBeBetweenOrEqualTo(percent, 0, 100, nameof(percent));
- this.Value = percent;
- }
-
- ///
- /// Gets the alpha value.
- ///
- public int Value { get; }
-
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- float alpha = this.Value / 100f;
- int sourceY = sourceRectangle.Y;
- int sourceBottom = sourceRectangle.Bottom;
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
- Vector4 alphaVector = new Vector4(1, 1, 1, alpha);
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- startY,
- endY,
- y =>
- {
- if (y >= sourceY && y < sourceBottom)
- {
- for (int x = startX; x < endX; x++)
- {
- Vector4 color = Color.ToNonPremultiplied(sourcePixels[x, y]).ToVector4();
- color *= alphaVector;
- targetPixels[x, y] = Color.FromNonPremultiplied(new Color(color));
- }
-
- this.OnRowProcessed();
- }
- });
-
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/BackgroundColorProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/BackgroundColorProcessor.cs
deleted file mode 100644
index e78987d23a..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/BackgroundColorProcessor.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System;
- using System.Threading.Tasks;
-
- ///
- /// Sets the background color of the image.
- ///
- public class BackgroundColorProcessor : ImageProcessor
- {
- ///
- /// The epsilon for comparing floating point numbers.
- ///
- private const float Epsilon = 0.001f;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The to set the background color to.
- public BackgroundColorProcessor(Color color)
- {
- this.Value = Color.FromNonPremultiplied(color);
- }
-
- ///
- /// Gets the background color value.
- ///
- public Color Value { get; }
-
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- int sourceY = sourceRectangle.Y;
- int sourceBottom = sourceRectangle.Bottom;
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
- Color backgroundColor = this.Value;
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- startY,
- endY,
- y =>
- {
- if (y >= sourceY && y < sourceBottom)
- {
- for (int x = startX; x < endX; x++)
- {
- Color color = sourcePixels[x, y];
- float a = color.A;
-
- if (a < 1 && a > 0)
- {
- color = Color.Lerp(color, backgroundColor, .5f);
- }
-
- if (Math.Abs(a) < Epsilon)
- {
- color = backgroundColor;
- }
-
- targetPixels[x, y] = color;
- }
-
- this.OnRowProcessed();
- }
- });
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Binarization/ThresholdProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Binarization/ThresholdProcessor.cs
deleted file mode 100644
index 60b49d0eec..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Binarization/ThresholdProcessor.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System;
- using System.Threading.Tasks;
-
- ///
- /// An to perform binary threshold filtering against an
- /// . The image will be converted to greyscale before thresholding
- /// occurs.
- ///
- public class ThresholdProcessor : ImageProcessor
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The threshold to split the image. Must be between 0 and 1.
- ///
- /// is less than 0 or is greater than 1.
- ///
- public ThresholdProcessor(float threshold)
- {
- Guard.MustBeBetweenOrEqualTo(threshold, 0, 1, nameof(threshold));
- this.Value = threshold;
- }
-
- ///
- /// Gets the threshold value.
- ///
- public float Value { get; }
-
- ///
- /// The color to use for pixels that are above the threshold.
- ///
- public Color UpperColor => Color.White;
-
- ///
- /// The color to use for pixels that fall below the threshold.
- ///
- public Color LowerColor => Color.Black;
-
- ///
- protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
- {
- new GreyscaleBt709Processor().Apply(source, source, sourceRectangle);
- }
-
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- float threshold = this.Value;
- Color upper = this.UpperColor;
- Color lower = this.LowerColor;
- int sourceY = sourceRectangle.Y;
- int sourceBottom = sourceRectangle.Bottom;
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- startY,
- endY,
- y =>
- {
- if (y >= sourceY && y < sourceBottom)
- {
- for (int x = startX; x < endX; x++)
- {
- Color color = sourcePixels[x, y];
-
- // Any channel will do since it's greyscale.
- targetPixels[x, y] = color.B >= threshold ? upper : lower;
- }
- this.OnRowProcessed();
- }
- });
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/BlendProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/BlendProcessor.cs
deleted file mode 100644
index 5de0741fae..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/BlendProcessor.cs
+++ /dev/null
@@ -1,86 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Threading.Tasks;
-
- ///
- /// Combines two images together by blending the pixels.
- ///
- public class BlendProcessor : ImageProcessor
- {
- ///
- /// The image to blend.
- ///
- private readonly ImageBase blend;
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The image to blend with the currently processing image.
- /// Disposal of this image is the responsibility of the developer.
- ///
- /// The opacity of the image to blend. Between 0 and 100.
- public BlendProcessor(ImageBase image, int alpha = 100)
- {
- Guard.MustBeBetweenOrEqualTo(alpha, 0, 100, nameof(alpha));
- this.blend = image;
- this.Value = alpha;
- }
-
- ///
- /// Gets the alpha percentage value.
- ///
- public int Value { get; }
-
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- int sourceY = sourceRectangle.Y;
- int sourceBottom = sourceRectangle.Bottom;
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
- Rectangle bounds = this.blend.Bounds;
- float alpha = this.Value / 100f;
-
- using (PixelAccessor toBlendPixels = this.blend.Lock())
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- startY,
- endY,
- y =>
- {
- if (y >= sourceY && y < sourceBottom)
- {
- for (int x = startX; x < endX; x++)
- {
- Color color = sourcePixels[x, y];
-
- if (bounds.Contains(x, y))
- {
- Color blendedColor = toBlendPixels[x, y];
-
- if (blendedColor.A > 0)
- {
- // Lerping colors is dependent on the alpha of the blended color
- float alphaFactor = alpha > 0 ? alpha : blendedColor.A;
- color = Color.Lerp(color, blendedColor, alphaFactor);
- }
- }
-
- targetPixels[x, y] = color;
- }
-
- this.OnRowProcessed();
- }
- });
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/BrightnessProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/BrightnessProcessor.cs
deleted file mode 100644
index 6710ff5938..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/BrightnessProcessor.cs
+++ /dev/null
@@ -1,69 +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;
-
- ///
- /// An to change the brightness of an .
- ///
- public class BrightnessProcessor : ImageProcessor
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The new brightness of the image. Must be between -100 and 100.
- ///
- /// is less than -100 or is greater than 100.
- ///
- public BrightnessProcessor(int brightness)
- {
- Guard.MustBeBetweenOrEqualTo(brightness, -100, 100, nameof(brightness));
- this.Value = brightness;
- }
-
- ///
- /// Gets the brightness value.
- ///
- public int Value { get; }
-
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- float brightness = this.Value / 100f;
- int sourceY = sourceRectangle.Y;
- int sourceBottom = sourceRectangle.Bottom;
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- startY,
- endY,
- y =>
- {
- if (y >= sourceY && y < sourceBottom)
- {
- for (int x = startX; x < endX; x++)
- {
- Color color = Color.Expand(sourcePixels[x, y]);
-
- Vector3 vector3 = color.ToVector3();
- vector3 += new Vector3(brightness);
-
- targetPixels[x, y] = Color.Compress(new Color(vector3, color.A));
- }
- this.OnRowProcessed();
- }
- });
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/BlackWhiteProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/BlackWhiteProcessor.cs
deleted file mode 100644
index 7fc3240d00..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/BlackWhiteProcessor.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Converts the colors of the image to their black and white equivalent.
- ///
- public class BlackWhiteProcessor : ColorMatrixFilter
- {
- ///
- public override Matrix4x4 Matrix => new Matrix4x4()
- {
- M11 = 1.5f,
- M12 = 1.5f,
- M13 = 1.5f,
- M21 = 1.5f,
- M22 = 1.5f,
- M23 = 1.5f,
- M31 = 1.5f,
- M32 = 1.5f,
- M33 = 1.5f,
- M41 = -1f,
- M42 = -1f,
- M43 = -1f,
- };
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/AchromatomalyProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/AchromatomalyProcessor.cs
deleted file mode 100644
index d5740ec284..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/AchromatomalyProcessor.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Converts the colors of the image recreating Achromatomaly (Color desensitivity) color blindness.
- ///
- public class AchromatomalyProcessor : ColorMatrixFilter
- {
- ///
- public override Matrix4x4 Matrix => new Matrix4x4()
- {
- M11 = .618f,
- M12 = .163f,
- M13 = .163f,
- M21 = .320f,
- M22 = .775f,
- M23 = .320f,
- M31 = .062f,
- M32 = .062f,
- M33 = .516f
- };
-
- ///
- public override bool Compand => false;
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/AchromatopsiaProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/AchromatopsiaProcessor.cs
deleted file mode 100644
index 6f2f7c2693..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/AchromatopsiaProcessor.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Converts the colors of the image recreating Achromatopsia (Monochrome) color blindness.
- ///
- public class AchromatopsiaProcessor : ColorMatrixFilter
- {
- ///
- public override Matrix4x4 Matrix => new Matrix4x4()
- {
- M11 = .299f,
- M12 = .299f,
- M13 = .299f,
- M21 = .587f,
- M22 = .587f,
- M23 = .587f,
- M31 = .114f,
- M32 = .114f,
- M33 = .114f
- };
-
- ///
- public override bool Compand => false;
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/DeuteranomalyProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/DeuteranomalyProcessor.cs
deleted file mode 100644
index fed09991f6..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/DeuteranomalyProcessor.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Converts the colors of the image recreating Deuteranomaly (Green-Weak) color blindness.
- ///
- public class DeuteranomalyProcessor : ColorMatrixFilter
- {
- ///
- public override Matrix4x4 Matrix => new Matrix4x4()
- {
- M11 = 0.8f,
- M12 = 0.258f,
- M21 = 0.2f,
- M22 = 0.742f,
- M23 = 0.142f,
- M33 = 0.858f
- };
-
- ///
- public override bool Compand => false;
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/DeuteranopiaProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/DeuteranopiaProcessor.cs
deleted file mode 100644
index 0ef190861b..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/DeuteranopiaProcessor.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Converts the colors of the image recreating Deuteranopia (Green-Blind) color blindness.
- ///
- public class DeuteranopiaProcessor : ColorMatrixFilter
- {
- ///
- public override Matrix4x4 Matrix => new Matrix4x4()
- {
- M11 = 0.625f,
- M12 = 0.7f,
- M21 = 0.375f,
- M22 = 0.3f,
- M23 = 0.3f,
- M33 = 0.7f
- };
-
- ///
- public override bool Compand => false;
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/ProtanomalyProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/ProtanomalyProcessor.cs
deleted file mode 100644
index b7152a68e4..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/ProtanomalyProcessor.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Converts the colors of the image recreating Protanopia (Red-Weak) color blindness.
- ///
- public class ProtanomalyProcessor : ColorMatrixFilter
- {
- ///
- public override Matrix4x4 Matrix => new Matrix4x4()
- {
- M11 = 0.817f,
- M12 = 0.333f,
- M21 = 0.183f,
- M22 = 0.667f,
- M23 = 0.125f,
- M33 = 0.875f
- };
-
- ///
- public override bool Compand => false;
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/ProtanopiaProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/ProtanopiaProcessor.cs
deleted file mode 100644
index 7984be139b..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/ProtanopiaProcessor.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Converts the colors of the image recreating Protanopia (Red-Blind) color blindness.
- ///
- public class ProtanopiaProcessor : ColorMatrixFilter
- {
- ///
- public override Matrix4x4 Matrix => new Matrix4x4()
- {
- M11 = 0.567f,
- M12 = 0.558f,
- M21 = 0.433f,
- M22 = 0.442f,
- M23 = 0.242f,
- M33 = 0.758f
- };
-
- ///
- public override bool Compand => false;
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/README.md b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/README.md
deleted file mode 100644
index 209f3b67bd..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-Color blindness matrices adapted from and tested against:
-
-http://web.archive.org/web/20090413045433/http://nofunc.org/Color_Matrix_Library
-http://www.color-blindness.com/coblis-color-blindness-simulator/
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/TritanomalyProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/TritanomalyProcessor.cs
deleted file mode 100644
index 618da36bb9..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/TritanomalyProcessor.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Converts the colors of the image recreating Tritanomaly (Blue-Weak) color blindness.
- ///
- public class TritanomalyProcessor : ColorMatrixFilter
- {
- ///
- public override Matrix4x4 Matrix => new Matrix4x4()
- {
- M11 = 0.967f,
- M21 = 0.33f,
- M22 = 0.733f,
- M23 = 0.183f,
- M32 = 0.267f,
- M33 = 0.817f
- };
-
- ///
- public override bool Compand => false;
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/TritanopiaProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/TritanopiaProcessor.cs
deleted file mode 100644
index e53de7a69a..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorBlindness/TritanopiaProcessor.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Converts the colors of the image recreating Tritanopia (Blue-Blind) color blindness.
- ///
- public class TritanopiaProcessor : ColorMatrixFilter
- {
- ///
- public override Matrix4x4 Matrix => new Matrix4x4()
- {
- M11 = 0.95f,
- M21 = 0.05f,
- M22 = 0.433f,
- M23 = 0.475f,
- M32 = 0.567f,
- M33 = 0.525f
- };
-
- ///
- public override bool Compand => false;
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorMatrixFilter.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorMatrixFilter.cs
deleted file mode 100644
index d27ea5c6d5..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/ColorMatrixFilter.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
- using System.Threading.Tasks;
-
- ///
- /// The color matrix filter.
- ///
- public abstract class ColorMatrixFilter : ImageProcessor, IColorMatrixFilter
- {
- ///
- public abstract Matrix4x4 Matrix { get; }
-
- ///
- public virtual bool Compand => true;
-
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
- Matrix4x4 matrix = this.Matrix;
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- startY,
- endY,
- y =>
- {
- for (int x = startX; x < endX; x++)
- {
- targetPixels[x, y] = this.ApplyMatrix(sourcePixels[x, y], matrix);
- }
-
- this.OnRowProcessed();
- });
- }
- }
-
- ///
- /// Applies the color matrix against the given color.
- ///
- /// The source color.
- /// The matrix.
- ///
- /// The .
- ///
- private Color ApplyMatrix(Color color, Matrix4x4 matrix)
- {
- bool compand = this.Compand;
-
- if (compand)
- {
- color = Color.Expand(color);
- }
-
- Vector3 transformed = Vector3.Transform(color.ToVector3(), matrix);
- return compand ? Color.Compress(new Color(transformed, color.A)) : new Color(transformed, color.A);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/GreyscaleBt601Processor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/GreyscaleBt601Processor.cs
deleted file mode 100644
index b9a6daa6e7..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/GreyscaleBt601Processor.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Converts the colors of the image to greyscale applying the formula as specified by
- /// ITU-R Recommendation BT.601 .
- ///
- public class GreyscaleBt601Processor : ColorMatrixFilter
- {
- ///
- public override Matrix4x4 Matrix => new Matrix4x4()
- {
- M11 = .299f,
- M12 = .299f,
- M13 = .299f,
- M21 = .587f,
- M22 = .587f,
- M23 = .587f,
- M31 = .114f,
- M32 = .114f,
- M33 = .114f
- };
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/GreyscaleBt709Processor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/GreyscaleBt709Processor.cs
deleted file mode 100644
index 949e51e6a9..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/GreyscaleBt709Processor.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Converts the colors of the image to greyscale applying the formula as specified by
- /// ITU-R Recommendation BT.709 .
- ///
- public class GreyscaleBt709Processor : ColorMatrixFilter
- {
- ///
- public override Matrix4x4 Matrix => new Matrix4x4()
- {
- M11 = .2126f,
- M12 = .2126f,
- M13 = .2126f,
- M21 = .7152f,
- M22 = .7152f,
- M23 = .7152f,
- M31 = .0722f,
- M32 = .0722f,
- M33 = .0722f
- };
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/GreyscaleMode.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/GreyscaleMode.cs
deleted file mode 100644
index 269c1179ef..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/GreyscaleMode.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// Provides enumeration over the various greyscale methods available.
- ///
- public enum GreyscaleMode
- {
- ///
- /// ITU-R Recommendation BT.709
- ///
- Bt709,
-
- ///
- /// ITU-R Recommendation BT.601
- ///
- Bt601
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/HueProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/HueProcessor.cs
deleted file mode 100644
index da7d4631c5..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/HueProcessor.cs
+++ /dev/null
@@ -1,81 +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;
-
- public class HueProcessor : ColorMatrixFilter
- {
- ///
- /// The used to alter the image.
- ///
- private Matrix4x4 matrix;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The new brightness of the image. Must be between -100 and 100.
- public HueProcessor(float angle)
- {
- // Wrap the angle round at 360.
- angle = angle % 360;
-
- // Make sure it's not negative.
- while (angle < 0)
- {
- angle += 360;
- }
-
- this.Angle = angle;
- }
-
- ///
- /// Gets the rotation value.
- ///
- public float Angle { get; }
-
- ///
- public override Matrix4x4 Matrix => this.matrix;
-
- ///
- public override bool Compand => false;
-
- ///
- protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
- {
- float radians = (float)ImageMaths.DegreesToRadians(this.Angle);
- double cosradians = Math.Cos(radians);
- double sinradians = Math.Sin(radians);
-
- float lumR = .213f;
- float lumG = .715f;
- float lumB = .072f;
-
- float oneMinusLumR = 1 - lumR;
- float oneMinusLumG = 1 - lumG;
- float oneMinusLumB = 1 - lumB;
-
- // The matrix is set up to preserve the luminance of the image.
- // See http://graficaobscura.com/matrix/index.html
- // Number are taken from https://msdn.microsoft.com/en-us/library/jj192162(v=vs.85).aspx
- Matrix4x4 matrix4X4 = new Matrix4x4()
- {
- M11 = (float)(lumR + (cosradians * oneMinusLumR) - (sinradians * lumR)),
- M12 = (float)(lumR - (cosradians * lumR) - (sinradians * 0.143)),
- M13 = (float)(lumR - (cosradians * lumR) - (sinradians * oneMinusLumR)),
- M21 = (float)(lumG - (cosradians * lumG) - (sinradians * lumG)),
- M22 = (float)(lumG + (cosradians * oneMinusLumG) + (sinradians * 0.140)),
- M23 = (float)(lumG - (cosradians * lumG) + (sinradians * lumG)),
- M31 = (float)(lumB - (cosradians * lumB) + (sinradians * oneMinusLumB)),
- M32 = (float)(lumB - (cosradians * lumB) - (sinradians * 0.283)),
- M33 = (float)(lumB + (cosradians * oneMinusLumB) + (sinradians * lumB))
- };
-
- this.matrix = matrix4X4;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/IColorMatrixFilter.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/IColorMatrixFilter.cs
deleted file mode 100644
index 5a0c766848..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/IColorMatrixFilter.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Encapsulates properties and methods for creating processors that utilize a matrix to
- /// alter the image pixels.
- ///
- public interface IColorMatrixFilter : IImageProcessor
- {
- ///
- /// Gets the used to alter the image.
- ///
- Matrix4x4 Matrix { get; }
-
- ///
- /// Gets a value indicating whether to compress
- /// or expand individual pixel colors the value on processing.
- ///
- bool Compand { get; }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/KodachromeProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/KodachromeProcessor.cs
deleted file mode 100644
index 91c436460e..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/KodachromeProcessor.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Converts the colors of the image recreating an old Kodachrome camera effect.
- ///
- public class KodachromeProcessor : ColorMatrixFilter
- {
- ///
- public override Matrix4x4 Matrix => new Matrix4x4()
- {
- M11 = 0.6997023f,
- M22 = 0.4609577f,
- M33 = 0.397218f,
- M41 = 0.005f,
- M42 = -0.005f,
- M43 = 0.005f
- };
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/LomographProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/LomographProcessor.cs
deleted file mode 100644
index 2422994337..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/LomographProcessor.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Converts the colors of the image recreating an old Lomograph effect.
- ///
- public class LomographProcessor : ColorMatrixFilter
- {
- ///
- public override Matrix4x4 Matrix => new Matrix4x4()
- {
- M11 = 1.5f,
- M22 = 1.45f,
- M33 = 1.11f,
- M41 = -.1f,
- M42 = .0f,
- M43 = -.08f
- };
-
- ///
- protected override void AfterApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
- {
- new VignetteProcessor { Color = new Color(0, 10 / 255f, 0) }.Apply(target, target, targetRectangle);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/PolaroidProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/PolaroidProcessor.cs
deleted file mode 100644
index ea6f85a390..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/PolaroidProcessor.cs
+++ /dev/null
@@ -1,45 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Converts the colors of the image recreating an old Polaroid effect.
- ///
- public class PolaroidProcessor : ColorMatrixFilter
- {
- ///
- public override Matrix4x4 Matrix => new Matrix4x4()
- {
- M11 = 1.538f,
- M12 = -0.062f,
- M13 = -0.262f,
- M21 = -0.022f,
- M22 = 1.578f,
- M23 = -0.022f,
- M31 = .216f,
- M32 = -.16f,
- M33 = 1.5831f,
- M41 = 0.02f,
- M42 = -0.05f,
- M43 = -0.05f
- };
-
- ///
- protected override void AfterApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
- {
- new VignetteProcessor { Color = new Color(102 / 255f, 34 / 255f, 0) }.Apply(target, target, targetRectangle);
- new GlowProcessor
- {
- Color = new Color(1, 153 / 255f, 102 / 255f, .7f),
- RadiusX = target.Width / 4f,
- RadiusY = target.Width / 4f
- }
- .Apply(target, target, targetRectangle);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/SaturationProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/SaturationProcessor.cs
deleted file mode 100644
index abc00bfb61..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/SaturationProcessor.cs
+++ /dev/null
@@ -1,75 +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;
-
- ///
- /// An to change the saturation of an .
- ///
- public class SaturationProcessor : ColorMatrixFilter
- {
- ///
- /// The saturation to be applied to the image.
- ///
- private readonly int saturation;
-
- ///
- /// The used to alter the image.
- ///
- private Matrix4x4 matrix;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The new saturation of the image. Must be between -100 and 100.
- ///
- /// is less than -100 or is greater than 100.
- ///
- public SaturationProcessor(int saturation)
- {
- Guard.MustBeBetweenOrEqualTo(saturation, -100, 100, nameof(saturation));
- this.saturation = saturation;
- }
-
- ///
- public override Matrix4x4 Matrix => this.matrix;
-
- ///
- protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
- {
- float saturationFactor = this.saturation / 100f;
-
- // Stop at -1 to prevent inversion.
- saturationFactor++;
-
- // The matrix is set up to "shear" the colour space using the following set of values.
- // Note that each colour component has an effective luminance which contributes to the
- // overall brightness of the pixel.
- // See http://graficaobscura.com/matrix/index.html
- float saturationComplement = 1.0f - saturationFactor;
- float saturationComplementR = 0.3086f * saturationComplement;
- float saturationComplementG = 0.6094f * saturationComplement;
- float saturationComplementB = 0.0820f * saturationComplement;
-
- Matrix4x4 matrix4X4 = new Matrix4x4()
- {
- M11 = saturationComplementR + saturationFactor,
- M12 = saturationComplementR,
- M13 = saturationComplementR,
- M21 = saturationComplementG,
- M22 = saturationComplementG + saturationFactor,
- M23 = saturationComplementG,
- M31 = saturationComplementB,
- M32 = saturationComplementB,
- M33 = saturationComplementB + saturationFactor,
- };
-
- this.matrix = matrix4X4;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/SepiaProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/SepiaProcessor.cs
deleted file mode 100644
index da68013110..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ColorMatrix/SepiaProcessor.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Converts the colors of the image to their sepia equivalent.
- /// The formula used matches the svg specification.
- ///
- public class SepiaProcessor : ColorMatrixFilter
- {
- ///
- public override Matrix4x4 Matrix => new Matrix4x4()
- {
- M11 = .393f,
- M12 = .349f,
- M13 = .272f,
- M21 = .769f,
- M22 = .686f,
- M23 = .534f,
- M31 = .189f,
- M32 = .168f,
- M33 = .131f
- };
-
- ///
- public override bool Compand => false;
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/ContrastProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/ContrastProcessor.cs
deleted file mode 100644
index 19f564be4d..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/ContrastProcessor.cs
+++ /dev/null
@@ -1,70 +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;
-
- ///
- /// An to change the contrast of an .
- ///
- public class ContrastProcessor : ImageProcessor
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The new contrast of the image. Must be between -100 and 100.
- ///
- /// is less than -100 or is greater than 100.
- ///
- public ContrastProcessor(int contrast)
- {
- Guard.MustBeBetweenOrEqualTo(contrast, -100, 100, nameof(contrast));
- this.Value = contrast;
- }
-
- ///
- /// Gets the contrast value.
- ///
- public int Value { get; }
-
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- float contrast = (100f + this.Value) / 100f;
- int sourceY = sourceRectangle.Y;
- int sourceBottom = sourceRectangle.Bottom;
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
- Vector4 contrastVector = new Vector4(contrast, contrast, contrast, 1);
- Vector4 shiftVector = new Vector4(.5f, .5f, .5f, 1);
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- startY,
- endY,
- y =>
- {
- if (y >= sourceY && y < sourceBottom)
- {
- for (int x = startX; x < endX; x++)
- {
- Vector4 color = Color.Expand(sourcePixels[x, y]).ToVector4();
- color -= shiftVector;
- color *= contrastVector;
- color += shiftVector;
- targetPixels[x, y] = Color.Compress(new Color(color));
- }
- this.OnRowProcessed();
- }
- });
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/BoxBlurProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/BoxBlurProcessor.cs
deleted file mode 100644
index 042288ffdc..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/BoxBlurProcessor.cs
+++ /dev/null
@@ -1,103 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// Applies a Box blur filter to the image.
- ///
- public class BoxBlurProcessor : Convolution2PassFilter
- {
- ///
- /// The maximum size of the kernal in either direction.
- ///
- private readonly int kernelSize;
-
- ///
- /// The vertical kernel
- ///
- private float[,] kernelY;
-
- ///
- /// The horizontal kernel
- ///
- private float[,] kernelX;
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The 'radius' value representing the size of the area to sample.
- ///
- public BoxBlurProcessor(int radius = 7)
- {
- this.kernelSize = (radius * 2) + 1;
- }
-
- ///
- public override float[,] KernelX => this.kernelX;
-
- ///
- public override float[,] KernelY => this.kernelY;
-
- ///
- protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
- {
- if (this.kernelY == null)
- {
- this.kernelY = this.CreateBoxKernel(false);
- }
-
- if (this.kernelX == null)
- {
- this.kernelX = this.CreateBoxKernel(true);
- }
- }
-
- ///
- /// Create a 1 dimensional Box kernel.
- ///
- /// Whether to calculate a horizontal kernel.
- /// The
- private float[,] CreateBoxKernel(bool horizontal)
- {
- int size = this.kernelSize;
- float[,] kernel = horizontal ? new float[1, size] : new float[size, 1];
- float sum = 0.0f;
-
- for (int i = 0; i < size; i++)
- {
- float x = 1;
- sum += x;
- if (horizontal)
- {
- kernel[0, i] = x;
- }
- else
- {
- kernel[i, 0] = x;
- }
- }
-
- // Normalise kernel so that the sum of all weights equals 1
- if (horizontal)
- {
- for (int i = 0; i < size; i++)
- {
- kernel[0, i] = kernel[0, i] / sum;
- }
- }
- else
- {
- for (int i = 0; i < size; i++)
- {
- kernel[i, 0] = kernel[i, 0] / sum;
- }
- }
-
- return kernel;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/Convolution2DFilter.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/Convolution2DFilter.cs
deleted file mode 100644
index b16a528db4..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/Convolution2DFilter.cs
+++ /dev/null
@@ -1,113 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System;
- using System.Threading.Tasks;
-
- ///
- /// Defines a filter that uses two one-dimensional matrices to perform convolution against an image.
- ///
- public abstract class Convolution2DFilter : ImageProcessor
- {
- ///
- /// Gets the horizontal gradient operator.
- ///
- public abstract float[,] KernelX { get; }
-
- ///
- /// Gets the vertical gradient operator.
- ///
- public abstract float[,] KernelY { get; }
-
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- float[,] kernelX = this.KernelX;
- float[,] kernelY = this.KernelY;
- int kernelYHeight = kernelY.GetLength(0);
- int kernelYWidth = kernelY.GetLength(1);
- int kernelXHeight = kernelX.GetLength(0);
- int kernelXWidth = kernelX.GetLength(1);
- int radiusY = kernelYHeight >> 1;
- int radiusX = kernelXWidth >> 1;
-
- int sourceY = sourceRectangle.Y;
- int sourceBottom = sourceRectangle.Bottom;
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
- int maxY = sourceBottom - 1;
- int maxX = endX - 1;
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- startY,
- endY,
- y =>
- {
- if (y >= sourceY && y < sourceBottom)
- {
- for (int x = startX; x < endX; x++)
- {
- float rX = 0;
- float gX = 0;
- float bX = 0;
- float rY = 0;
- float gY = 0;
- float bY = 0;
-
- // Apply each matrix multiplier to the color components for each pixel.
- for (int fy = 0; fy < kernelYHeight; fy++)
- {
- int fyr = fy - radiusY;
- int offsetY = y + fyr;
-
- offsetY = offsetY.Clamp(0, maxY);
-
- for (int fx = 0; fx < kernelXWidth; fx++)
- {
- int fxr = fx - radiusX;
- int offsetX = x + fxr;
-
- offsetX = offsetX.Clamp(0, maxX);
-
- Color currentColor = sourcePixels[offsetX, offsetY];
- float r = currentColor.R;
- float g = currentColor.G;
- float b = currentColor.B;
-
- if (fy < kernelXHeight)
- {
- rX += kernelX[fy, fx] * r;
- gX += kernelX[fy, fx] * g;
- bX += kernelX[fy, fx] * b;
- }
-
- if (fx < kernelYWidth)
- {
- rY += kernelY[fy, fx] * r;
- gY += kernelY[fy, fx] * g;
- bY += kernelY[fy, fx] * b;
- }
- }
- }
-
- float red = (float)Math.Sqrt((rX * rX) + (rY * rY));
- float green = (float)Math.Sqrt((gX * gX) + (gY * gY));
- float blue = (float)Math.Sqrt((bX * bX) + (bY * bY));
-
- Color targetColor = targetPixels[x, y];
- targetPixels[x, y] = new Color(red, green, blue, targetColor.A);
- }
- this.OnRowProcessed();
- }
- });
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/Convolution2PassFilter.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/Convolution2PassFilter.cs
deleted file mode 100644
index c9031dfd7a..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/Convolution2PassFilter.cs
+++ /dev/null
@@ -1,113 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Threading.Tasks;
-
- ///
- /// Defines a filter that uses two one-dimensional matrices to perform two-pass convolution against an image.
- ///
- public abstract class Convolution2PassFilter : ImageProcessor
- {
- ///
- /// Gets the horizontal gradient operator.
- ///
- public abstract float[,] KernelX { get; }
-
- ///
- /// Gets the vertical gradient operator.
- ///
- public abstract float[,] KernelY { get; }
-
- ///
- protected override void Apply(
- ImageBase target,
- ImageBase source,
- Rectangle targetRectangle,
- Rectangle sourceRectangle,
- int startY,
- int endY)
- {
- float[,] kernelX = this.KernelX;
- float[,] kernelY = this.KernelY;
-
- ImageBase firstPass = new Image(source.Width, source.Height);
- this.ApplyConvolution(firstPass, source, sourceRectangle, startY, endY, kernelX);
- this.ApplyConvolution(target, firstPass, sourceRectangle, startY, endY, kernelY);
- }
-
- ///
- /// Applies the process to the specified portion of the specified at the specified location
- /// and with the specified size.
- ///
- /// 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 index of the row within the source image to start processing.
- /// The index of the row within the source image to end processing.
- /// The kernel operator.
- private void ApplyConvolution(
- ImageBase target,
- ImageBase source,
- Rectangle sourceRectangle,
- int startY,
- int endY,
- float[,] kernel)
- {
- int kernelHeight = kernel.GetLength(0);
- int kernelWidth = kernel.GetLength(1);
- int radiusY = kernelHeight >> 1;
- int radiusX = kernelWidth >> 1;
-
- int sourceBottom = sourceRectangle.Bottom;
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
- int maxY = sourceBottom - 1;
- int maxX = endX - 1;
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- startY,
- endY,
- y =>
- {
- for (int x = startX; x < endX; x++)
- {
- Color destination = new Color();
-
- // Apply each matrix multiplier to the color components for each pixel.
- for (int fy = 0; fy < kernelHeight; fy++)
- {
- int fyr = fy - radiusY;
- int offsetY = y + fyr;
-
- offsetY = offsetY.Clamp(0, maxY);
-
- for (int fx = 0; fx < kernelWidth; fx++)
- {
- int fxr = fx - radiusX;
- int offsetX = x + fxr;
-
- offsetX = offsetX.Clamp(0, maxX);
-
- Color currentColor = sourcePixels[offsetX, offsetY];
- destination += kernel[fy, fx] * currentColor;
- }
- }
-
- targetPixels[x, y] = destination;
- }
-
- this.OnRowProcessed();
- });
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/ConvolutionFilter.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/ConvolutionFilter.cs
deleted file mode 100644
index 8ddcab4a5d..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/ConvolutionFilter.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Threading.Tasks;
-
- ///
- /// Defines a filter that uses a 2 dimensional matrix to perform convolution against an image.
- ///
- public abstract class ConvolutionFilter : ImageProcessor
- {
- ///
- /// Gets the 2d gradient operator.
- ///
- public abstract float[,] KernelXY { get; }
-
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- float[,] kernelX = this.KernelXY;
- int kernelLength = kernelX.GetLength(0);
- int radius = kernelLength >> 1;
-
- int sourceY = sourceRectangle.Y;
- int sourceBottom = sourceRectangle.Bottom;
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
- int maxY = sourceBottom - 1;
- int maxX = endX - 1;
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- startY,
- endY,
- y =>
- {
- if (y >= sourceY && y < sourceBottom)
- {
- for (int x = startX; x < endX; x++)
- {
- float rX = 0;
- float gX = 0;
- float bX = 0;
-
- // Apply each matrix multiplier to the color components for each pixel.
- for (int fy = 0; fy < kernelLength; fy++)
- {
- int fyr = fy - radius;
- int offsetY = y + fyr;
-
- offsetY = offsetY.Clamp(0, maxY);
-
- for (int fx = 0; fx < kernelLength; fx++)
- {
- int fxr = fx - radius;
- int offsetX = x + fxr;
-
- offsetX = offsetX.Clamp(0, maxX);
-
- Color currentColor = sourcePixels[offsetX, offsetY];
- float r = currentColor.R;
- float g = currentColor.G;
- float b = currentColor.B;
-
- rX += kernelX[fy, fx] * r;
- gX += kernelX[fy, fx] * g;
- bX += kernelX[fy, fx] * b;
- }
- }
-
- float red = rX;
- float green = gX;
- float blue = bX;
-
- targetPixels[x, y] = new Color(red, green, blue);
- }
- this.OnRowProcessed();
- }
- });
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DFilter.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DFilter.cs
deleted file mode 100644
index ce4aa0b2aa..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DFilter.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// Defines a filter that detects edges within an image using two
- /// one-dimensional matrices.
- ///
- public abstract class EdgeDetector2DFilter : Convolution2DFilter, IEdgeDetectorFilter
- {
- ///
- public bool Greyscale { get; set; }
-
- ///
- protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
- {
- if (this.Greyscale)
- {
- new GreyscaleBt709Processor().Apply(source, source, sourceRectangle);
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorFilter.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorFilter.cs
deleted file mode 100644
index 7a18bb96b3..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorFilter.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// Defines a filter that detects edges within an image using a single
- /// two dimensional matrix.
- ///
- public abstract class EdgeDetectorFilter : ConvolutionFilter, IEdgeDetectorFilter
- {
- ///
- public bool Greyscale { get; set; }
-
- ///
- protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
- {
- if (this.Greyscale)
- {
- new GreyscaleBt709Processor().Apply(source, source, sourceRectangle);
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorFilter.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorFilter.cs
deleted file mode 100644
index b90f0d2ea2..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorFilter.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// Provides properties and methods allowing the detection of edges within an image.
- ///
- public interface IEdgeDetectorFilter : IImageProcessor
- {
- ///
- /// Gets or sets a value indicating whether to convert the
- /// image to greyscale before performing edge detection.
- ///
- bool Greyscale { get; set; }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs
deleted file mode 100644
index 5af8182412..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// The Kayyali operator filter.
- ///
- ///
- public class KayyaliProcessor : EdgeDetector2DFilter
- {
- ///
- public override float[,] KernelX => new float[,]
- {
- { 6, 0, -6 },
- { 0, 0, 0 },
- { -6, 0, 6 }
- };
-
- ///
- public override float[,] KernelY => new float[,]
- {
- { -6, 0, 6 },
- { 0, 0, 0 },
- { 6, 0, -6 }
- };
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/KirschProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/KirschProcessor.cs
deleted file mode 100644
index 24a561572e..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/KirschProcessor.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// The Kirsch operator filter.
- ///
- ///
- public class KirschProcessor : EdgeDetector2DFilter
- {
- ///
- public override float[,] KernelX => new float[,]
- {
- { 5, 5, 5 },
- { -3, 0, -3 },
- { -3, -3, -3 }
- };
-
- ///
- public override float[,] KernelY => new float[,]
- {
- { 5, -3, -3 },
- { 5, 0, -3 },
- { 5, -3, -3 }
- };
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs
deleted file mode 100644
index a66d692537..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// The Laplacian 3 x 3 operator filter.
- ///
- ///
- public class Laplacian3X3Processor : EdgeDetectorFilter
- {
- ///
- public override float[,] KernelXY => new float[,]
- {
- { -1, -1, -1 },
- { -1, 8, -1 },
- { -1, -1, -1 }
- };
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs
deleted file mode 100644
index f2d3d885ee..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// The Laplacian 5 x 5 operator filter.
- ///
- ///
- public class Laplacian5X5Processor : EdgeDetectorFilter
- {
- ///
- public override float[,] KernelXY => new float[,]
- {
- { -1, -1, -1, -1, -1 },
- { -1, -1, -1, -1, -1 },
- { -1, -1, 24, -1, -1 },
- { -1, -1, -1, -1, -1 },
- { -1, -1, -1, -1, -1 }
- };
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs
deleted file mode 100644
index 0aae3020a9..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// The Laplacian of Gaussian operator filter.
- ///
- ///
- public class LaplacianOfGaussianProcessor : EdgeDetectorFilter
- {
- ///
- public override float[,] KernelXY => new float[,]
- {
- { 0, 0, -1, 0, 0 },
- { 0, -1, -2, -1, 0 },
- { -1, -2, 16, -2, -1 },
- { 0, -1, -2, -1, 0 },
- { 0, 0, -1, 0, 0 }
- };
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/PrewittProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/PrewittProcessor.cs
deleted file mode 100644
index 3a5bbe9860..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/PrewittProcessor.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// The Prewitt operator filter.
- ///
- ///
- public class PrewittProcessor : EdgeDetector2DFilter
- {
- ///
- public override float[,] KernelX => new float[,]
- {
- { -1, 0, 1 },
- { -1, 0, 1 },
- { -1, 0, 1 }
- };
-
- ///
- public override float[,] KernelY => new float[,]
- {
- { 1, 1, 1 },
- { 0, 0, 0 },
- { -1, -1, -1 }
- };
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs
deleted file mode 100644
index 0a61664184..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// The Roberts Cross operator filter.
- ///
- ///
- public class RobertsCrossProcessor : EdgeDetector2DFilter
- {
- ///
- public override float[,] KernelX => new float[,]
- {
- { 1, 0 },
- { 0, -1 }
- };
-
- ///
- public override float[,] KernelY => new float[,]
- {
- { 0, 1 },
- { -1, 0 }
- };
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/ScharrProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/ScharrProcessor.cs
deleted file mode 100644
index 80308a1409..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/ScharrProcessor.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// The Scharr operator filter.
- ///
- ///
- public class ScharrProcessor : EdgeDetector2DFilter
- {
- ///
- public override float[,] KernelX => new float[,]
- {
- { -3, 0, 3 },
- { -10, 0, 10 },
- { -3, 0, 3 }
- };
-
- ///
- public override float[,] KernelY => new float[,]
- {
- { 3, 10, 3 },
- { 0, 0, 0 },
- { -3, -10, -3 }
- };
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/SobelProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/SobelProcessor.cs
deleted file mode 100644
index 39f7d350d2..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/EdgeDetection/SobelProcessor.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// The Sobel operator filter.
- ///
- ///
- public class SobelProcessor : EdgeDetector2DFilter
- {
- ///
- public override float[,] KernelX => new float[,]
- {
- { -1, 0, 1 },
- { -2, 0, 2 },
- { -1, 0, 1 }
- };
-
- ///
- public override float[,] KernelY => new float[,]
- {
- { 1, 2, 1 },
- { 0, 0, 0 },
- { -1, -2, -1 }
- };
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/GuassianBlurProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/GuassianBlurProcessor.cs
deleted file mode 100644
index 6288ea963b..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/GuassianBlurProcessor.cs
+++ /dev/null
@@ -1,140 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System;
-
- ///
- /// Applies a Gaussian blur filter to the image.
- ///
- public class GuassianBlurProcessor : Convolution2PassFilter
- {
- ///
- /// The maximum size of the kernal in either direction.
- ///
- private readonly int kernelSize;
-
- ///
- /// The spread of the blur.
- ///
- private readonly float sigma;
-
- ///
- /// The vertical kernel
- ///
- private float[,] kernelY;
-
- ///
- /// The horizontal kernel
- ///
- private float[,] kernelX;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The 'sigma' value representing the weight of the blur.
- public GuassianBlurProcessor(float sigma = 3f)
- {
- this.kernelSize = ((int)Math.Ceiling(sigma) * 2) + 1;
- this.sigma = sigma;
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The 'radius' value representing the size of the area to sample.
- ///
- public GuassianBlurProcessor(int radius)
- {
- this.kernelSize = (radius * 2) + 1;
- this.sigma = radius;
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The 'sigma' value representing the weight of the blur.
- ///
- ///
- /// The 'radius' value representing the size of the area to sample.
- /// This should be at least twice the sigma value.
- ///
- public GuassianBlurProcessor(float sigma, int radius)
- {
- this.kernelSize = (radius * 2) + 1;
- this.sigma = sigma;
- }
-
- ///
- public override float[,] KernelX => this.kernelX;
-
- ///
- public override float[,] KernelY => this.kernelY;
-
- ///
- protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
- {
- if (this.kernelY == null)
- {
- this.kernelY = this.CreateGaussianKernel(false);
- }
-
- if (this.kernelX == null)
- {
- this.kernelX = this.CreateGaussianKernel(true);
- }
- }
-
- ///
- /// Create a 1 dimensional Gaussian kernel using the Gaussian G(x) function
- ///
- /// Whether to calculate a horizontal kernel.
- /// The
- private float[,] CreateGaussianKernel(bool horizontal)
- {
- int size = this.kernelSize;
- float weight = this.sigma;
- float[,] kernel = horizontal ? new float[1, size] : new float[size, 1];
- float sum = 0.0f;
-
- float midpoint = (size - 1) / 2f;
- for (int i = 0; i < size; i++)
- {
- float x = i - midpoint;
- float gx = ImageMaths.Gaussian(x, weight);
- sum += gx;
- if (horizontal)
- {
- kernel[0, i] = gx;
- }
- else
- {
- kernel[i, 0] = gx;
- }
- }
-
- // Normalise kernel so that the sum of all weights equals 1
- if (horizontal)
- {
- for (int i = 0; i < size; i++)
- {
- kernel[0, i] = kernel[0, i] / sum;
- }
- }
- else
- {
- for (int i = 0; i < size; i++)
- {
- kernel[i, 0] = kernel[i, 0] / sum;
- }
- }
-
- return kernel;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/GuassianSharpenProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/GuassianSharpenProcessor.cs
deleted file mode 100644
index 9d70732d20..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/Convolution/GuassianSharpenProcessor.cs
+++ /dev/null
@@ -1,178 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System;
-
- ///
- /// Applies a Gaussian sharpening filter to the image.
- ///
- public class GuassianSharpenProcessor : Convolution2PassFilter
- {
- ///
- /// The maximum size of the kernal in either direction.
- ///
- private readonly int kernelSize;
-
- ///
- /// The spread of the blur.
- ///
- private readonly float sigma;
-
- ///
- /// The vertical kernel
- ///
- private float[,] kernelY;
-
- ///
- /// The horizontal kernel
- ///
- private float[,] kernelX;
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The 'sigma' value representing the weight of the sharpening.
- ///
- public GuassianSharpenProcessor(float sigma = 3f)
- {
- this.kernelSize = ((int)Math.Ceiling(sigma) * 2) + 1;
- this.sigma = sigma;
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The 'radius' value representing the size of the area to sample.
- ///
- public GuassianSharpenProcessor(int radius)
- {
- this.kernelSize = (radius * 2) + 1;
- this.sigma = radius;
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The 'sigma' value representing the weight of the sharpen.
- ///
- ///
- /// The 'radius' value representing the size of the area to sample.
- /// This should be at least twice the sigma value.
- ///
- public GuassianSharpenProcessor(float sigma, int radius)
- {
- this.kernelSize = (radius * 2) + 1;
- this.sigma = sigma;
- }
-
- ///
- public override float[,] KernelX => this.kernelX;
-
- ///
- public override float[,] KernelY => this.kernelY;
-
- ///
- protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
- {
- if (this.kernelY == null)
- {
- this.kernelY = this.CreateGaussianKernel(false);
- }
-
- if (this.kernelX == null)
- {
- this.kernelX = this.CreateGaussianKernel(true);
- }
- }
-
- ///
- /// Create a 1 dimensional Gaussian kernel using the Gaussian G(x) function
- ///
- /// Whether to calculate a horizontal kernel.
- /// The
- private float[,] CreateGaussianKernel(bool horizontal)
- {
- int size = this.kernelSize;
- float weight = this.sigma;
- float[,] kernel = horizontal ? new float[1, size] : new float[size, 1];
- float sum = 0;
-
- float midpoint = (size - 1) / 2f;
- for (int i = 0; i < size; i++)
- {
- float x = i - midpoint;
- float gx = ImageMaths.Gaussian(x, weight);
- sum += gx;
- if (horizontal)
- {
- kernel[0, i] = gx;
- }
- else
- {
- kernel[i, 0] = gx;
- }
- }
-
- // Invert the kernel for sharpening.
- int midpointRounded = (int)midpoint;
-
- if (horizontal)
- {
- for (int i = 0; i < size; i++)
- {
- if (i == midpointRounded)
- {
- // Calculate central value
- kernel[0, i] = (2f * sum) - kernel[0, i];
- }
- else
- {
- // invert value
- kernel[0, i] = -kernel[0, i];
- }
- }
- }
- else
- {
- for (int i = 0; i < size; i++)
- {
- if (i == midpointRounded)
- {
- // Calculate central value
- kernel[i, 0] = (2 * sum) - kernel[i, 0];
- }
- else
- {
- // invert value
- kernel[i, 0] = -kernel[i, 0];
- }
- }
- }
-
- // Normalise kernel so that the sum of all weights equals 1
- if (horizontal)
- {
- for (int i = 0; i < size; i++)
- {
- kernel[0, i] = kernel[0, i] / sum;
- }
- }
- else
- {
- for (int i = 0; i < size; i++)
- {
- kernel[i, 0] = kernel[i, 0] / sum;
- }
- }
-
- return kernel;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/GlowProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/GlowProcessor.cs
deleted file mode 100644
index e046be6a9d..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/GlowProcessor.cs
+++ /dev/null
@@ -1,64 +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;
-
- ///
- /// Creates a glow effect on the image
- ///
- public class GlowProcessor : ImageProcessor
- {
- ///
- /// Gets or sets the glow color to apply.
- ///
- public Color Color { get; set; } = Color.White;
-
- ///
- /// Gets or sets the the x-radius.
- ///
- public float RadiusX { get; set; }
-
- ///
- /// Gets or sets the the y-radius.
- ///
- public float RadiusY { get; set; }
-
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
- Color glowColor = this.Color;
- Vector2 centre = Rectangle.Center(targetRectangle).ToVector2();
- float rX = this.RadiusX > 0 ? this.RadiusX : targetRectangle.Width / 2f;
- float rY = this.RadiusY > 0 ? this.RadiusY : targetRectangle.Height / 2f;
- float maxDistance = (float)Math.Sqrt(rX * rX + rY * rY);
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- startY,
- endY,
- y =>
- {
- for (int x = startX; x < endX; x++)
- {
- float distance = Vector2.Distance(centre, new Vector2(x, y));
- Color sourceColor = sourcePixels[x, y];
- targetPixels[x, y] = Color.Lerp(glowColor, sourceColor, .5f * (distance / maxDistance));
- }
-
- this.OnRowProcessed();
- });
- }
- }
- }
-}
-
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/InvertProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/InvertProcessor.cs
deleted file mode 100644
index 1f319b92b5..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/InvertProcessor.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
- using System.Threading.Tasks;
-
- ///
- /// An to invert the colors of an .
- ///
- public class InvertProcessor : ImageProcessor
- {
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- int sourceY = sourceRectangle.Y;
- int sourceBottom = sourceRectangle.Bottom;
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
- Vector3 inverseVector = Vector3.One;
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- startY,
- endY,
- y =>
- {
- if (y >= sourceY && y < sourceBottom)
- {
- for (int x = startX; x < endX; x++)
- {
- Color color = sourcePixels[x, y];
- Vector3 vector = inverseVector - color.ToVector3();
- targetPixels[x, y] = new Color(vector, color.A);
- }
-
- this.OnRowProcessed();
- }
- });
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/PixelateProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/PixelateProcessor.cs
deleted file mode 100644
index 4769799b5d..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/PixelateProcessor.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System;
- using System.Collections.Generic;
- using System.Threading.Tasks;
-
- ///
- /// An to invert the colors of an .
- ///
- public class PixelateProcessor : ImageProcessor
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The size of the pixels. Must be greater than 0.
- ///
- /// is less than 0 or equal to 0.
- ///
- public PixelateProcessor(int size)
- {
- Guard.MustBeGreaterThan(size, 0, nameof(size));
- this.Value = size;
- }
-
- ///
- /// Gets or the pixel size.
- ///
- public int Value { get; }
-
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- int sourceY = sourceRectangle.Y;
- int sourceBottom = sourceRectangle.Bottom;
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
- int size = this.Value;
- int offset = this.Value / 2;
-
- // Get the range on the y-plane to choose from.
- IEnumerable range = EnumerableExtensions.SteppedRange(startY, i => i < endY, size);
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.ForEach(
- range,
- y =>
- {
- if (y >= sourceY && y < sourceBottom)
- {
- for (int x = startX; x < endX; x += size)
- {
- int offsetX = offset;
- int offsetY = offset;
-
- // Make sure that the offset is within the boundary of the
- // image.
- while (y + offsetY >= sourceBottom)
- {
- offsetY--;
- }
-
- while (x + offsetX >= endX)
- {
- offsetX--;
- }
-
- // Get the pixel color in the centre of the soon to be pixelated area.
- // ReSharper disable AccessToDisposedClosure
- Color pixel = sourcePixels[x + offsetX, y + offsetY];
-
- // For each pixel in the pixelate size, set it to the centre color.
- for (int l = y; l < y + size && l < sourceBottom; l++)
- {
- for (int k = x; k < x + size && k < endX; k++)
- {
- targetPixels[k, l] = pixel;
- }
- }
- }
-
- this.OnRowProcessed();
- }
- });
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Processors/VignetteProcessor.cs b/src/ImageProcessorCore - Copy/Filters/Processors/VignetteProcessor.cs
deleted file mode 100644
index 1fd4630ed3..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Processors/VignetteProcessor.cs
+++ /dev/null
@@ -1,63 +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;
-
- ///
- /// Creates a vignette effect on the image
- ///
- public class VignetteProcessor : ImageProcessor
- {
- ///
- /// Gets or sets the vignette color to apply.
- ///
- public Color Color { get; set; } = Color.Black;
-
- ///
- /// Gets or sets the the x-radius.
- ///
- public float RadiusX { get; set; }
-
- ///
- /// Gets or sets the the y-radius.
- ///
- public float RadiusY { get; set; }
-
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- int startX = sourceRectangle.X;
- int endX = sourceRectangle.Right;
- Color vignetteColor = this.Color;
- Vector2 centre = Rectangle.Center(targetRectangle).ToVector2();
- float rX = this.RadiusX > 0 ? this.RadiusX : targetRectangle.Width / 2f;
- float rY = this.RadiusY > 0 ? this.RadiusY : targetRectangle.Height / 2f;
- float maxDistance = (float)Math.Sqrt(rX * rX + rY * rY);
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- startY,
- endY,
- y =>
- {
- for (int x = startX; x < endX; x++)
- {
- float distance = Vector2.Distance(centre, new Vector2(x, y));
- Color sourceColor = sourcePixels[x, y];
- targetPixels[x, y] = Color.Lerp(vignetteColor, sourceColor, 1 - .9f * distance / maxDistance);
- }
- this.OnRowProcessed();
- });
- }
- }
- }
-}
-
diff --git a/src/ImageProcessorCore - Copy/Filters/Saturation.cs b/src/ImageProcessorCore - Copy/Filters/Saturation.cs
deleted file mode 100644
index 93c69fe3e7..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Saturation.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Alters the saturation component of the image.
- ///
- /// The image this method extends.
- /// The new saturation of the image. Must be between -100 and 100.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Saturation(this Image source, int amount, ProgressEventHandler progressHandler = null)
- {
- return Saturation(source, amount, source.Bounds, progressHandler);
- }
-
- ///
- /// Alters the saturation component of the image.
- ///
- /// The image this method extends.
- /// The new saturation of the image. Must be between -100 and 100.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Saturation(this Image source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- SaturationProcessor processor = new SaturationProcessor(amount);
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Filters/Sepia.cs b/src/ImageProcessorCore - Copy/Filters/Sepia.cs
deleted file mode 100644
index 27d19b3194..0000000000
--- a/src/ImageProcessorCore - Copy/Filters/Sepia.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Applies sepia toning to the image.
- ///
- /// The image this method extends.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Sepia(this Image source, ProgressEventHandler progressHandler = null)
- {
- return Sepia(source, source.Bounds, progressHandler);
- }
-
- ///
- /// Applies sepia toning to the image.
- ///
- /// The image this method extends.
- ///
- /// The structure that specifies the portion of the image object to alter.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Sepia(this Image source, Rectangle rectangle, ProgressEventHandler progressHandler = null)
- {
- SepiaProcessor processor = new SepiaProcessor();
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(rectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpBitsPerPixel.cs b/src/ImageProcessorCore - Copy/Formats/Bmp/BmpBitsPerPixel.cs
deleted file mode 100644
index e7de3bc295..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpBitsPerPixel.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Enumerates the available bits per pixel for bitmap.
- ///
- public enum BmpBitsPerPixel
- {
- ///
- /// 24 bits per pixel. Each pixel consists of 3 bytes.
- ///
- Pixel24 = 3,
-
- ///
- /// 32 bits per pixel. Each pixel consists of 4 bytes.
- ///
- Pixel32 = 4,
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpCompression.cs b/src/ImageProcessorCore - Copy/Formats/Bmp/BmpCompression.cs
deleted file mode 100644
index de3c66495d..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpCompression.cs
+++ /dev/null
@@ -1,63 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Defines how the compression type of the image data
- /// in the bitmap file.
- ///
- internal enum BmpCompression
- {
- ///
- /// Each image row has a multiple of four elements. If the
- /// row has less elements, zeros will be added at the right side.
- /// The format depends on the number of bits, stored in the info header.
- /// If the number of bits are one, four or eight each pixel data is
- /// a index to the palette. If the number of bits are sixteen,
- /// twenty-four or thirty-two each pixel contains a color.
- ///
- RGB = 0,
-
- ///
- /// Two bytes are one data record. If the first byte is not zero, the
- /// next two half bytes will be repeated as much as the value of the first byte.
- /// If the first byte is zero, the record has different meanings, depending
- /// on the second byte. If the second byte is zero, it is the end of the row,
- /// if it is one, it is the end of the image.
- /// Not supported at the moment.
- ///
- RLE8 = 1,
-
- ///
- /// Two bytes are one data record. If the first byte is not zero, the
- /// next byte will be repeated as much as the value of the first byte.
- /// If the first byte is zero, the record has different meanings, depending
- /// on the second byte. If the second byte is zero, it is the end of the row,
- /// if it is one, it is the end of the image.
- /// Not supported at the moment.
- ///
- RLE4 = 2,
-
- ///
- /// Each image row has a multiple of four elements. If the
- /// row has less elements, zeros will be added at the right side.
- /// Not supported at the moment.
- ///
- BitFields = 3,
-
- ///
- /// The bitmap contains a JPG image.
- /// Not supported at the moment.
- ///
- JPEG = 4,
-
- ///
- /// The bitmap contains a PNG image.
- /// Not supported at the moment.
- ///
- PNG = 5
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpDecoder.cs b/src/ImageProcessorCore - Copy/Formats/Bmp/BmpDecoder.cs
deleted file mode 100644
index 03d45f1122..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpDecoder.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
-
- ///
- /// Image decoder for generating an image out of a Windows bitmap stream.
- ///
- ///
- /// Does not support the following formats at the moment:
- ///
- /// - JPG
- /// - PNG
- /// - RLE4
- /// - RLE8
- /// - BitFields
- ///
- /// Formats will be supported in a later releases. We advise always
- /// to use only 24 Bit Windows bitmaps.
- ///
- public class BmpDecoder : IImageDecoder
- {
- ///
- /// Gets the size of the header for this image type.
- ///
- /// The size of the header.
- public int HeaderSize => 2;
-
- ///
- /// Returns a value indicating whether the supports the specified
- /// file header.
- ///
- /// The containing the file extension.
- ///
- /// True if the decoder supports the file extension; otherwise, false.
- ///
- public bool IsSupportedFileExtension(string extension)
- {
- Guard.NotNullOrEmpty(extension, "extension");
-
- extension = extension.StartsWith(".") ? extension.Substring(1) : extension;
-
- return extension.Equals("BMP", StringComparison.OrdinalIgnoreCase)
- || extension.Equals("DIP", StringComparison.OrdinalIgnoreCase);
- }
-
- ///
- /// Returns a value indicating whether the supports the specified
- /// file header.
- ///
- /// The containing the file header.
- ///
- /// True if the decoder supports the file header; otherwise, false.
- ///
- public bool IsSupportedFileFormat(byte[] header)
- {
- bool isBmp = false;
- if (header.Length >= 2)
- {
- isBmp = header[0] == 0x42 && // B
- header[1] == 0x4D; // M
- }
-
- return isBmp;
- }
-
- ///
- /// Decodes the image from the specified stream to the .
- ///
- /// The to decode to.
- /// The containing image data.
- public void Decode(Image image, Stream stream)
- {
- new BmpDecoderCore().Decode(image, stream);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpDecoderCore.cs b/src/ImageProcessorCore - Copy/Formats/Bmp/BmpDecoderCore.cs
deleted file mode 100644
index 9c2bc45b9a..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpDecoderCore.cs
+++ /dev/null
@@ -1,445 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
- using System.Threading.Tasks;
-
- ///
- /// Performs the bmp decoding operation.
- ///
- internal sealed class BmpDecoderCore
- {
- ///
- /// The mask for the red part of the color for 16 bit rgb bitmaps.
- ///
- private const int Rgb16RMask = 0x00007C00;
-
- ///
- /// The mask for the green part of the color for 16 bit rgb bitmaps.
- ///
- private const int Rgb16GMask = 0x000003E0;
-
- ///
- /// The mask for the blue part of the color for 16 bit rgb bitmaps.
- ///
- private const int Rgb16BMask = 0x0000001F;
-
- ///
- /// The stream to decode from.
- ///
- private Stream currentStream;
-
- ///
- /// The file header containing general information.
- /// TODO: Why is this not used? We advance the stream but do not use the values parsed.
- ///
- private BmpFileHeader fileHeader;
-
- ///
- /// The info header containing detailed information about the bitmap.
- ///
- private BmpInfoHeader infoHeader;
-
- ///
- /// Decodes the image from the specified this._stream and sets
- /// the data to image.
- ///
- /// The type of pixels contained within the image.
- /// The image, where the data should be set to.
- /// Cannot be null (Nothing in Visual Basic).
- /// The this._stream, where the image should be
- /// decoded from. Cannot be null (Nothing in Visual Basic).
- ///
- /// is null.
- /// - or -
- /// is null.
- ///
- public void Decode(Image image, Stream stream)
- where TPackedVector : IPackedVector, new()
- {
- this.currentStream = stream;
-
- try
- {
- this.ReadFileHeader();
- this.ReadInfoHeader();
-
- // see http://www.drdobbs.com/architecture-and-design/the-bmp-file-format-part-1/184409517
- // If the height is negative, then this is a Windows bitmap whose origin
- // is the upper-left corner and not the lower-left.The inverted flag
- // indicates a lower-left origin.Our code will be outputting an
- // upper-left origin pixel array.
- bool inverted = false;
- if (this.infoHeader.Height < 0)
- {
- inverted = true;
- this.infoHeader.Height = -this.infoHeader.Height;
- }
-
- int colorMapSize = -1;
-
- if (this.infoHeader.ClrUsed == 0)
- {
- if (this.infoHeader.BitsPerPixel == 1 ||
- this.infoHeader.BitsPerPixel == 4 ||
- this.infoHeader.BitsPerPixel == 8)
- {
- colorMapSize = (int)Math.Pow(2, this.infoHeader.BitsPerPixel) * 4;
- }
- }
- else
- {
- colorMapSize = this.infoHeader.ClrUsed * 4;
- }
-
- byte[] palette = null;
-
- if (colorMapSize > 0)
- {
- // 255 * 4
- if (colorMapSize > 1020)
- {
- throw new ImageFormatException($"Invalid bmp colormap size '{colorMapSize}'");
- }
-
- palette = new byte[colorMapSize];
-
- this.currentStream.Read(palette, 0, colorMapSize);
- }
-
- if (this.infoHeader.Width > image.MaxWidth || this.infoHeader.Height > image.MaxHeight)
- {
- throw new ArgumentOutOfRangeException(
- $"The input bitmap '{this.infoHeader.Width}x{this.infoHeader.Height}' is "
- + $"bigger then the max allowed size '{image.MaxWidth}x{image.MaxHeight}'");
- }
-
- TPackedVector[] imageData = new TPackedVector[this.infoHeader.Width * this.infoHeader.Height];
-
- switch (this.infoHeader.Compression)
- {
- case BmpCompression.RGB:
- if (this.infoHeader.HeaderSize != 40)
- {
- throw new ImageFormatException(
- $"Header Size value '{this.infoHeader.HeaderSize}' is not valid.");
- }
-
- if (this.infoHeader.BitsPerPixel == 32)
- {
- this.ReadRgb32(imageData, this.infoHeader.Width, this.infoHeader.Height, inverted);
- }
- else if (this.infoHeader.BitsPerPixel == 24)
- {
- this.ReadRgb24(imageData, this.infoHeader.Width, this.infoHeader.Height, inverted);
- }
- else if (this.infoHeader.BitsPerPixel == 16)
- {
- this.ReadRgb16(imageData, this.infoHeader.Width, this.infoHeader.Height, inverted);
- }
- else if (this.infoHeader.BitsPerPixel <= 8)
- {
- this.ReadRgbPalette(
- imageData,
- palette,
- this.infoHeader.Width,
- this.infoHeader.Height,
- this.infoHeader.BitsPerPixel,
- inverted);
- }
-
- break;
- default:
- throw new NotSupportedException("Does not support this kind of bitmap files.");
- }
-
- image.SetPixels(this.infoHeader.Width, this.infoHeader.Height, imageData);
- }
- catch (IndexOutOfRangeException e)
- {
- throw new ImageFormatException("Bitmap does not have a valid format.", e);
- }
- }
-
- ///
- /// Returns the y- value based on the given height.
- ///
- /// The y- value representing the current row.
- /// The height of the bitmap.
- /// The representing the inverted value.
- private static int Invert(int y, int height, bool inverted)
- {
- int row;
-
- if (!inverted)
- {
- row = height - y - 1;
- }
- else
- {
- row = y;
- }
-
- return row;
- }
-
- ///
- /// Reads the color palette from the stream.
- ///
- /// The image data to assign the palette to.
- /// The containing the colors.
- /// The width of the bitmap.
- /// The height of the bitmap.
- /// The number of bits per pixel.
- private void ReadRgbPalette(float[] imageData, byte[] colors, int width, int height, int bits, bool inverted)
- {
- // Pixels per byte (bits per pixel)
- int ppb = 8 / bits;
-
- int arrayWidth = (width + ppb - 1) / ppb;
-
- // Bit mask
- int mask = 0xFF >> (8 - bits);
-
- byte[] data = new byte[arrayWidth * height];
-
- this.currentStream.Read(data, 0, data.Length);
-
- // Rows are aligned on 4 byte boundaries
- int alignment = arrayWidth % 4;
- if (alignment != 0)
- {
- alignment = 4 - alignment;
- }
-
- Parallel.For(
- 0,
- height,
- y =>
- {
- int rowOffset = y * (arrayWidth + alignment);
-
- for (int x = 0; x < arrayWidth; x++)
- {
- int offset = rowOffset + x;
-
- // Revert the y value, because bitmaps are saved from down to top
- int row = Invert(y, height, inverted);
-
- int colOffset = x * ppb;
-
- for (int shift = 0; shift < ppb && (colOffset + shift) < width; shift++)
- {
- int colorIndex = ((data[offset] >> (8 - bits - (shift * bits))) & mask) * 4;
- int arrayOffset = ((row * width) + (colOffset + shift)) * 4;
-
- // We divide by 255 as we will store the colors in our floating point format.
- // Stored in r-> g-> b-> a order.
- imageData[arrayOffset] = colors[colorIndex + 2] / 255f; // r
- imageData[arrayOffset + 1] = colors[colorIndex + 1] / 255f; // g
- imageData[arrayOffset + 2] = colors[colorIndex] / 255f; // b
- imageData[arrayOffset + 3] = 1; // a
- }
- }
- });
- }
-
- ///
- /// Reads the 16 bit color palette from the stream
- ///
- /// The type of pixels contained within the image.
- /// The image data to assign the palette to.
- /// The width of the bitmap.
- /// The height of the bitmap.
- private void ReadRgb16(TPackedVector[] imageData, int width, int height, bool inverted)
- where TPackedVector : IPackedVector, new()
- {
- // We divide here as we will store the colors in our floating point format.
- const int ScaleR = 8; // 256/32
- const int ScaleG = 4; // 256/64
-
- int alignment;
- byte[] data = this.GetImageArray(width, height, 2, out alignment);
-
- Parallel.For(
- 0,
- height,
- y =>
- {
- int rowOffset = y * ((width * 2) + alignment);
-
- // Revert the y value, because bitmaps are saved from down to top
- int row = Invert(y, height, inverted);
-
- for (int x = 0; x < width; x++)
- {
- int offset = rowOffset + (x * 2);
-
- short temp = BitConverter.ToInt16(data, offset);
-
- byte r = (byte)(((temp & Rgb16RMask) >> 11) * ScaleR);
- byte g = (byte)(((temp & Rgb16GMask) >> 5) * ScaleG);
- byte b = (byte)((temp & Rgb16BMask) * ScaleR);
-
- int arrayOffset = ((row * width) + x);
-
- // Stored in b-> g-> r-> a order.
- TPackedVector packed = new TPackedVector();
- packed.PackBytes(b, g, r, 255);
- imageData[arrayOffset] = packed;
- }
- });
- }
-
- ///
- /// Reads the 24 bit color palette from the stream
- ///
- /// The type of pixels contained within the image.
- /// The image data to assign the palette to.
- /// The width of the bitmap.
- /// The height of the bitmap.
- private void ReadRgb24(TPackedVector[] imageData, int width, int height, bool inverted)
- where TPackedVector : IPackedVector, new()
- {
- int alignment;
- byte[] data = this.GetImageArray(width, height, 3, out alignment);
-
- Parallel.For(
- 0,
- height,
- y =>
- {
- int rowOffset = y * ((width * 3) + alignment);
-
- // Revert the y value, because bitmaps are saved from down to top
- int row = Invert(y, height, inverted);
-
- for (int x = 0; x < width; x++)
- {
- int offset = rowOffset + (x * 3);
- int arrayOffset = ((row * width) + x);
-
- // We divide by 255 as we will store the colors in our floating point format.
- // Stored in b-> g-> r-> a order.
- TPackedVector packed = new TPackedVector();
- packed.PackBytes(data[offset], data[offset + 1], data[offset + 2], 255);
- imageData[arrayOffset] = packed;
- }
- });
- }
-
- ///
- /// Reads the 32 bit color palette from the stream
- ///
- /// The type of pixels contained within the image.
- /// The image data to assign the palette to.
- /// The width of the bitmap.
- /// The height of the bitmap.
- private void ReadRgb32(TPackedVector[] imageData, int width, int height, bool inverted)
- where TPackedVector : IPackedVector, new()
- {
- int alignment;
- byte[] data = this.GetImageArray(width, height, 4, out alignment);
-
- Parallel.For(
- 0,
- height,
- y =>
- {
- int rowOffset = y * ((width * 4) + alignment);
-
- // Revert the y value, because bitmaps are saved from down to top
- int row = Invert(y, height, inverted);
-
- for (int x = 0; x < width; x++)
- {
- int offset = rowOffset + (x * 4);
- int arrayOffset = ((row * width) + x);
-
- // Stored in b-> g-> r-> a order.
- TPackedVector packed = new TPackedVector();
- packed.PackBytes(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]);
- imageData[arrayOffset] = packed;
- }
- });
- }
-
- ///
- /// Returns a containing the pixels for the current bitmap.
- ///
- /// The width of the bitmap.
- /// The height.
- /// The number of bytes per pixel.
- /// The alignment of the pixels.
- ///
- /// The containing the pixels.
- ///
- private byte[] GetImageArray(int width, int height, int bytes, out int alignment)
- {
- int dataWidth = width;
-
- alignment = (width * bytes) % 4;
-
- if (alignment != 0)
- {
- alignment = 4 - alignment;
- }
-
- int size = ((dataWidth * bytes) + alignment) * height;
-
- byte[] data = new byte[size];
-
- this.currentStream.Read(data, 0, size);
-
- return data;
- }
-
- ///
- /// Reads the from the stream.
- ///
- private void ReadInfoHeader()
- {
- byte[] data = new byte[BmpInfoHeader.Size];
-
- this.currentStream.Read(data, 0, BmpInfoHeader.Size);
-
- this.infoHeader = new BmpInfoHeader
- {
- HeaderSize = BitConverter.ToInt32(data, 0),
- Width = BitConverter.ToInt32(data, 4),
- Height = BitConverter.ToInt32(data, 8),
- Planes = BitConverter.ToInt16(data, 12),
- BitsPerPixel = BitConverter.ToInt16(data, 14),
- ImageSize = BitConverter.ToInt32(data, 20),
- XPelsPerMeter = BitConverter.ToInt32(data, 24),
- YPelsPerMeter = BitConverter.ToInt32(data, 28),
- ClrUsed = BitConverter.ToInt32(data, 32),
- ClrImportant = BitConverter.ToInt32(data, 36),
- Compression = (BmpCompression)BitConverter.ToInt32(data, 16)
- };
- }
-
- ///
- /// Reads the from the stream.
- ///
- private void ReadFileHeader()
- {
- byte[] data = new byte[BmpFileHeader.Size];
-
- this.currentStream.Read(data, 0, BmpFileHeader.Size);
-
- this.fileHeader = new BmpFileHeader
- {
- Type = BitConverter.ToInt16(data, 0),
- FileSize = BitConverter.ToInt32(data, 2),
- Reserved = BitConverter.ToInt32(data, 6),
- Offset = BitConverter.ToInt32(data, 10)
- };
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpEncoder.cs b/src/ImageProcessorCore - Copy/Formats/Bmp/BmpEncoder.cs
deleted file mode 100644
index 4b212d4ea0..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpEncoder.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
-
- ///
- /// Image encoder for writing an image to a stream as a Windows bitmap.
- ///
- /// The encoder can currently only write 24-bit rgb images to streams.
- public class BmpEncoder : IImageEncoder
- {
- ///
- /// Gets or sets the quality of output for images.
- ///
- /// Bitmap is a lossless format so this is not used in this encoder.
- public int Quality { get; set; }
-
- ///
- public string MimeType => "image/bmp";
-
- ///
- public string Extension => "bmp";
-
- ///
- /// Gets or sets the number of bits per pixel.
- ///
- public BmpBitsPerPixel BitsPerPixel { get; set; } = BmpBitsPerPixel.Pixel24;
-
- ///
- public bool IsSupportedFileExtension(string extension)
- {
- Guard.NotNullOrEmpty(extension, nameof(extension));
-
- extension = extension.StartsWith(".") ? extension.Substring(1) : extension;
-
- return extension.Equals(this.Extension, StringComparison.OrdinalIgnoreCase)
- || extension.Equals("dip", StringComparison.OrdinalIgnoreCase);
- }
-
- ///
- public void Encode(ImageBase image, Stream stream)
- where TPackedVector: IPackedVector
- {
- BmpEncoderCore encoder = new BmpEncoderCore();
- encoder.Encode(image, stream, this.BitsPerPixel);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpEncoderCore.cs b/src/ImageProcessorCore - Copy/Formats/Bmp/BmpEncoderCore.cs
deleted file mode 100644
index 2ad8e24e6e..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpEncoderCore.cs
+++ /dev/null
@@ -1,205 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
-
- using IO;
-
- ///
- /// Image encoder for writing an image to a stream as a Windows bitmap.
- ///
- /// The encoder can currently only write 24-bit rgb images to streams.
- internal sealed class BmpEncoderCore
- {
- ///
- /// The number of bits per pixel.
- ///
- private BmpBitsPerPixel bmpBitsPerPixel;
-
- ///
- /// Encodes the image to the specified stream from the .
- ///
- /// The type of pixels contained within the image.
- /// The to encode from.
- /// The to encode the image data to.
- /// The
- public void Encode(ImageBase image, Stream stream, BmpBitsPerPixel bitsPerPixel)
- where TPackedVector : IPackedVector
- {
- Guard.NotNull(image, nameof(image));
- Guard.NotNull(stream, nameof(stream));
-
- this.bmpBitsPerPixel = bitsPerPixel;
-
- int rowWidth = image.Width;
-
- // TODO: Check this for varying file formats.
- int amount = (image.Width * (int)this.bmpBitsPerPixel) % 4;
- if (amount != 0)
- {
- rowWidth += 4 - amount;
- }
-
- // Do not use IDisposable pattern here as we want to preserve the stream.
- EndianBinaryWriter writer = new EndianBinaryWriter(EndianBitConverter.Little, stream);
-
- int bpp = (int)this.bmpBitsPerPixel;
-
- BmpFileHeader fileHeader = new BmpFileHeader
- {
- Type = 19778, // BM
- Offset = 54,
- FileSize = 54 + (image.Height * rowWidth * bpp)
- };
-
- BmpInfoHeader infoHeader = new BmpInfoHeader
- {
- HeaderSize = 40,
- Height = image.Height,
- Width = image.Width,
- BitsPerPixel = (short)(8 * bpp),
- Planes = 1,
- ImageSize = image.Height * rowWidth * bpp,
- ClrUsed = 0,
- ClrImportant = 0
- };
-
- WriteHeader(writer, fileHeader);
- this.WriteInfo(writer, infoHeader);
- this.WriteImage(writer, image);
-
- writer.Flush();
- }
-
- ///
- /// Writes the bitmap header data to the binary stream.
- ///
- ///
- /// The containing the stream to write to.
- ///
- ///
- /// The containing the header data.
- ///
- private static void WriteHeader(EndianBinaryWriter writer, BmpFileHeader fileHeader)
- {
- writer.Write(fileHeader.Type);
- writer.Write(fileHeader.FileSize);
- writer.Write(fileHeader.Reserved);
- writer.Write(fileHeader.Offset);
- }
-
- ///
- /// Writes the bitmap information to the binary stream.
- ///
- ///
- /// The containing the stream to write to.
- ///
- ///
- /// The containing the detailed information about the image.
- ///
- private void WriteInfo(EndianBinaryWriter writer, BmpInfoHeader infoHeader)
- {
- writer.Write(infoHeader.HeaderSize);
- writer.Write(infoHeader.Width);
- writer.Write(infoHeader.Height);
- writer.Write(infoHeader.Planes);
- writer.Write(infoHeader.BitsPerPixel);
- writer.Write((int)infoHeader.Compression);
- writer.Write(infoHeader.ImageSize);
- writer.Write(infoHeader.XPelsPerMeter);
- writer.Write(infoHeader.YPelsPerMeter);
- writer.Write(infoHeader.ClrUsed);
- writer.Write(infoHeader.ClrImportant);
- }
-
- ///
- /// Writes the pixel data to the binary stream.
- ///
- /// The type of pixels contained within the image.
- ///
- /// The containing the stream to write to.
- ///
- ///
- /// The containing pixel data.
- ///
- private void WriteImage(EndianBinaryWriter writer, ImageBase image)
- where TPackedVector : IPackedVector
- {
- // TODO: Add more compression formats.
- int amount = (image.Width * (int)this.bmpBitsPerPixel) % 4;
- if (amount != 0)
- {
- amount = 4 - amount;
- }
-
- using (IPixelAccessor pixels = image.Lock())
- {
- switch (this.bmpBitsPerPixel)
- {
- case BmpBitsPerPixel.Pixel32:
- this.Write32bit(writer, pixels, amount);
- break;
-
- case BmpBitsPerPixel.Pixel24:
- this.Write24bit(writer, pixels, amount);
- break;
- }
- }
- }
-
- ///
- /// Writes the 32bit color palette to the stream.
- ///
- /// The containing the stream to write to.
- /// The containing pixel data.
- /// The amount to pad each row by.
- private void Write32bit(EndianBinaryWriter writer, IPixelAccessor pixels, int amount)
- {
- for (int y = pixels.Height - 1; y >= 0; y--)
- {
- for (int x = 0; x < pixels.Width; x++)
- {
- // Convert back to b-> g-> r-> a order.
- byte[] bytes = pixels[x, y].ToBytes();
- writer.Write(bytes);
- }
-
- // Pad
- for (int i = 0; i < amount; i++)
- {
- writer.Write((byte)0);
- }
- }
- }
-
- ///
- /// Writes the 24bit color palette to the stream.
- ///
- /// The containing the stream to write to.
- /// The containing pixel data.
- /// The amount to pad each row by.
- private void Write24bit(EndianBinaryWriter writer, IPixelAccessor pixels, int amount)
- {
- for (int y = pixels.Height - 1; y >= 0; y--)
- {
- for (int x = 0; x < pixels.Width; x++)
- {
- // Convert back to b-> g-> r-> a order.
- byte[] bytes = pixels[x, y].ToBytes();
- writer.Write(new[] { bytes[0], bytes[1], bytes[2] });
- }
-
- // Pad
- for (int i = 0; i < amount; i++)
- {
- writer.Write((byte)0);
- }
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpFileHeader.cs b/src/ImageProcessorCore - Copy/Formats/Bmp/BmpFileHeader.cs
deleted file mode 100644
index 6f626ee703..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpFileHeader.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Stores general information about the Bitmap file.
- ///
- ///
- ///
- /// The first two bytes of the Bitmap file format
- /// (thus the Bitmap header) are stored in big-endian order.
- /// All of the other integer values are stored in little-endian format
- /// (i.e. least-significant byte first).
- ///
- internal class BmpFileHeader
- {
- ///
- /// Defines of the data structure in the bitmap file.
- ///
- public const int Size = 14;
-
- ///
- /// Gets or sets the Bitmap identifier.
- /// The field used to identify the bitmap file: 0x42 0x4D
- /// (Hex code points for B and M)
- ///
- public short Type { get; set; }
-
- ///
- /// Gets or sets the size of the bitmap file in bytes.
- ///
- public int FileSize { get; set; }
-
- ///
- /// Gets or sets any reserved data; actual value depends on the application
- /// that creates the image.
- ///
- public int Reserved { get; set; }
-
- ///
- /// Gets or sets the offset, i.e. starting address, of the byte where
- /// the bitmap data can be found.
- ///
- public int Offset { get; set; }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpFormat.cs b/src/ImageProcessorCore - Copy/Formats/Bmp/BmpFormat.cs
deleted file mode 100644
index 6f640c4b9e..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpFormat.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Encapsulates the means to encode and decode bitmap images.
- ///
- public class BmpFormat : IImageFormat
- {
- ///
- public IImageDecoder Decoder => new BmpDecoder();
-
- ///
- public IImageEncoder Encoder => new BmpEncoder();
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpInfoHeader.cs b/src/ImageProcessorCore - Copy/Formats/Bmp/BmpInfoHeader.cs
deleted file mode 100644
index c21a52d21b..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Bmp/BmpInfoHeader.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-namespace ImageProcessorCore.Formats
-{
- ///
- /// This block of bytes tells the application detailed information
- /// about the image, which will be used to display the image on
- /// the screen.
- ///
- ///
- internal class BmpInfoHeader
- {
- ///
- /// Defines of the data structure in the bitmap file.
- ///
- public const int Size = 40;
-
- ///
- /// Gets or sets the size of this header (40 bytes)
- ///
- public int HeaderSize { get; set; }
-
- ///
- /// Gets or sets the bitmap width in pixels (signed integer).
- ///
- public int Width { get; set; }
-
- ///
- /// Gets or sets the bitmap height in pixels (signed integer).
- ///
- public int Height { get; set; }
-
- ///
- /// Gets or sets the number of color planes being used. Must be set to 1.
- ///
- public short Planes { get; set; }
-
- ///
- /// Gets or sets the number of bits per pixel, which is the color depth of the image.
- /// Typical values are 1, 4, 8, 16, 24 and 32.
- ///
- public short BitsPerPixel { get; set; }
-
- ///
- /// Gets or sets the compression method being used.
- /// See the next table for a list of possible values.
- ///
- public BmpCompression Compression { get; set; }
-
- ///
- /// Gets or sets the image size. This is the size of the raw bitmap data (see below),
- /// and should not be confused with the file size.
- ///
- public int ImageSize { get; set; }
-
- ///
- /// Gets or sets the horizontal resolution of the image.
- /// (pixel per meter, signed integer)
- ///
- public int XPelsPerMeter { get; set; }
-
- ///
- /// Gets or sets the vertical resolution of the image.
- /// (pixel per meter, signed integer)
- ///
- public int YPelsPerMeter { get; set; }
-
- ///
- /// Gets or sets the number of colors in the color palette,
- /// or 0 to default to 2^n.
- ///
- public int ClrUsed { get; set; }
-
- ///
- /// Gets or sets the number of important colors used,
- /// or 0 when every color is important{ get; set; } generally ignored.
- ///
- public int ClrImportant { get; set; }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Bmp/README.md b/src/ImageProcessorCore - Copy/Formats/Bmp/README.md
deleted file mode 100644
index d072838438..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Bmp/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-Encoder/Decoder adapted from:
-
-https://github.com/yufeih/Nine.Imaging/
-https://imagetools.codeplex.com/
-
-TODO:
-
-- Add support for all bitmap formats.
diff --git a/src/ImageProcessorCore - Copy/Formats/Gif/BitEncoder.cs b/src/ImageProcessorCore - Copy/Formats/Gif/BitEncoder.cs
deleted file mode 100644
index a0c633a194..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Gif/BitEncoder.cs
+++ /dev/null
@@ -1,132 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System.Collections.Generic;
-
- ///
- /// Handles the encoding of bits for compression.
- ///
- internal class BitEncoder
- {
- ///
- /// The inner list for collecting the bits.
- ///
- private readonly List list = new List();
-
- ///
- /// The current working bit.
- ///
- private int currentBit;
-
- ///
- /// The current value.
- ///
- private int currentValue;
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The initial bits.
- ///
- public BitEncoder(int initial)
- {
- this.IntitialBit = initial;
- }
-
- ///
- /// Gets or sets the intitial bit.
- ///
- public int IntitialBit { get; set; }
-
- ///
- /// The number of bytes in the encoder.
- ///
- public int Length => this.list.Count;
-
- ///
- /// Adds the current byte to the end of the encoder.
- ///
- ///
- /// The byte to add.
- ///
- public void Add(int item)
- {
- this.currentValue |= item << this.currentBit;
-
- this.currentBit += this.IntitialBit;
-
- while (this.currentBit >= 8)
- {
- byte value = (byte)(this.currentValue & 0XFF);
- this.currentValue = this.currentValue >> 8;
- this.currentBit -= 8;
- this.list.Add(value);
- }
- }
-
- ///
- /// Adds the collection of bytes to the end of the encoder.
- ///
- ///
- /// The collection of bytes to add.
- /// The collection itself cannot be null but can contain elements that are null.
- public void AddRange(byte[] collection)
- {
- this.list.AddRange(collection);
- }
-
- ///
- /// Copies a range of elements from the encoder to a compatible one-dimensional array,
- /// starting at the specified index of the target array.
- ///
- ///
- /// The zero-based index in the source at which copying begins.
- ///
- ///
- /// The one-dimensional Array that is the destination of the elements copied
- /// from . The Array must have zero-based indexing
- ///
- /// The zero-based index in array at which copying begins.
- /// The number of bytes to copy.
- public void CopyTo(int index, byte[] array, int arrayIndex, int count)
- {
- this.list.CopyTo(index, array, arrayIndex, count);
- }
-
- ///
- /// Removes all the bytes from the encoder.
- ///
- public void Clear()
- {
- this.list.Clear();
- }
-
- ///
- /// Copies the bytes into a new array.
- ///
- ///
- public byte[] ToArray()
- {
- return this.list.ToArray();
- }
-
- ///
- /// The end.
- ///
- internal void End()
- {
- while (this.currentBit > 0)
- {
- byte value = (byte)(this.currentValue & 0XFF);
- this.currentValue = this.currentValue >> 8;
- this.currentBit -= 8;
- this.list.Add(value);
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Gif/DisposalMethod.cs b/src/ImageProcessorCore - Copy/Formats/Gif/DisposalMethod.cs
deleted file mode 100644
index 4b0a019734..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Gif/DisposalMethod.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Provides enumeration for instructing the decoder what to do with the last image
- /// in an animation sequence.
- /// section 23
- ///
- public enum DisposalMethod
- {
- ///
- /// No disposal specified. The decoder is not required to take any action.
- ///
- Unspecified = 0,
-
- ///
- /// Do not dispose. The graphic is to be left in place.
- ///
- NotDispose = 1,
-
- ///
- /// Restore to background color. The area used by the graphic must be restored to
- /// the background color.
- ///
- RestoreToBackground = 2,
-
- ///
- /// Restore to previous. The decoder is required to restore the area overwritten by the
- /// graphic with what was there prior to rendering the graphic.
- ///
- RestoreToPrevious = 3
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Gif/GifConstants.cs b/src/ImageProcessorCore - Copy/Formats/Gif/GifConstants.cs
deleted file mode 100644
index 42949cf168..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Gif/GifConstants.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Constants that define specific points within a gif.
- ///
- internal sealed class GifConstants
- {
- ///
- /// The file type.
- ///
- public const string FileType = "GIF";
-
- ///
- /// The file version.
- ///
- public const string FileVersion = "89a";
-
- ///
- /// The extension block introducer !.
- ///
- public const byte ExtensionIntroducer = 0x21;
-
- ///
- /// The graphic control label.
- ///
- public const byte GraphicControlLabel = 0xF9;
-
- ///
- /// The application extension label.
- ///
- public const byte ApplicationExtensionLabel = 0xFF;
-
- ///
- /// The application identification.
- ///
- public const string ApplicationIdentification = "NETSCAPE2.0";
-
- ///
- /// The application block size.
- ///
- public const byte ApplicationBlockSize = 0x0b;
-
- ///
- /// The comment label.
- ///
- public const byte CommentLabel = 0xFE;
-
- ///
- /// The maximum comment length.
- ///
- public const int MaxCommentLength = 1024 * 8;
-
- ///
- /// The image descriptor label ,.
- ///
- public const byte ImageDescriptorLabel = 0x2C;
-
- ///
- /// The plain text label.
- ///
- public const byte PlainTextLabel = 0x01;
-
- ///
- /// The image label introducer ,.
- ///
- public const byte ImageLabel = 0x2C;
-
- ///
- /// The terminator.
- ///
- public const byte Terminator = 0;
-
- ///
- /// The end introducer trailer ;.
- ///
- public const byte EndIntroducer = 0x3B;
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Gif/GifDecoder.cs b/src/ImageProcessorCore - Copy/Formats/Gif/GifDecoder.cs
deleted file mode 100644
index 1abbcb2fb7..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Gif/GifDecoder.cs
+++ /dev/null
@@ -1,67 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
-
- ///
- /// Decoder for generating an image out of a gif encoded stream.
- ///
- public class GifDecoder : IImageDecoder
- {
- ///
- /// Gets the size of the header for this image type.
- ///
- /// The size of the header.
- public int HeaderSize => 6;
-
- ///
- /// Returns a value indicating whether the supports the specified
- /// file header.
- ///
- /// The containing the file extension.
- ///
- /// True if the decoder supports the file extension; otherwise, false.
- ///
- public bool IsSupportedFileExtension(string extension)
- {
- Guard.NotNullOrEmpty(extension, nameof(extension));
-
- extension = extension.StartsWith(".") ? extension.Substring(1) : extension;
- return extension.Equals("GIF", StringComparison.OrdinalIgnoreCase);
- }
-
- ///
- /// Returns a value indicating whether the supports the specified
- /// file header.
- ///
- /// The containing the file header.
- ///
- /// True if the decoder supports the file header; otherwise, false.
- ///
- public bool IsSupportedFileFormat(byte[] header)
- {
- return header.Length >= 6 &&
- header[0] == 0x47 && // G
- header[1] == 0x49 && // I
- header[2] == 0x46 && // F
- header[3] == 0x38 && // 8
- (header[4] == 0x39 || header[4] == 0x37) && // 9 or 7
- header[5] == 0x61; // a
- }
-
- ///
- /// Decodes the image from the specified stream to the .
- ///
- /// The to decode to.
- /// The containing image data.
- public void Decode(Image image, Stream stream)
- {
- new GifDecoderCore().Decode(image, stream);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Gif/GifDecoderCore.cs b/src/ImageProcessorCore - Copy/Formats/Gif/GifDecoderCore.cs
deleted file mode 100644
index 693f974c7a..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Gif/GifDecoderCore.cs
+++ /dev/null
@@ -1,428 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
-
- ///
- /// Performs the gif decoding operation.
- ///
- internal class GifDecoderCore
- {
- ///
- /// The image to decode the information to.
- ///
- private Image decodedImage;
-
- ///
- /// The currently loaded stream.
- ///
- private Stream currentStream;
-
- ///
- /// The global color table.
- ///
- private byte[] globalColorTable;
-
- ///
- /// The current frame.
- ///
- private float[] currentFrame;
-
- ///
- /// The logical screen descriptor.
- ///
- private GifLogicalScreenDescriptor logicalScreenDescriptor;
-
- ///
- /// The graphics control extension.
- ///
- private GifGraphicsControlExtension graphicsControlExtension;
-
- ///
- /// Decodes the stream to the image.
- ///
- /// The image to decode to.
- /// The stream containing image data.
- public void Decode(Image image, Stream stream)
- {
- this.decodedImage = image;
-
- this.currentStream = stream;
-
- // Skip the identifier
- this.currentStream.Seek(6, SeekOrigin.Current);
- this.ReadLogicalScreenDescriptor();
-
- if (this.logicalScreenDescriptor.GlobalColorTableFlag)
- {
- this.globalColorTable = new byte[this.logicalScreenDescriptor.GlobalColorTableSize * 3];
-
- // Read the global color table from the stream
- stream.Read(this.globalColorTable, 0, this.globalColorTable.Length);
- }
-
- // Loop though the respective gif parts and read the data.
- int nextFlag = stream.ReadByte();
- while (nextFlag != GifConstants.Terminator)
- {
- if (nextFlag == GifConstants.ImageLabel)
- {
- this.ReadFrame();
- }
- else if (nextFlag == GifConstants.ExtensionIntroducer)
- {
- int label = stream.ReadByte();
- switch (label)
- {
- case GifConstants.GraphicControlLabel:
- this.ReadGraphicalControlExtension();
- break;
- case GifConstants.CommentLabel:
- this.ReadComments();
- break;
- case GifConstants.ApplicationExtensionLabel:
- this.Skip(12); // No need to read.
- break;
- case GifConstants.PlainTextLabel:
- this.Skip(13); // Not supported by any known decoder.
- break;
- }
- }
- else if (nextFlag == GifConstants.EndIntroducer)
- {
- break;
- }
-
- nextFlag = stream.ReadByte();
- }
- }
-
- ///
- /// Reads the graphic control extension.
- ///
- private void ReadGraphicalControlExtension()
- {
- byte[] buffer = new byte[6];
-
- this.currentStream.Read(buffer, 0, buffer.Length);
-
- byte packed = buffer[1];
-
- this.graphicsControlExtension = new GifGraphicsControlExtension
- {
- DelayTime = BitConverter.ToInt16(buffer, 2),
- TransparencyIndex = buffer[4],
- TransparencyFlag = (packed & 0x01) == 1,
- DisposalMethod = (DisposalMethod)((packed & 0x1C) >> 2)
- };
- }
-
- ///
- /// Reads the image descriptor
- ///
- ///
- private GifImageDescriptor ReadImageDescriptor()
- {
- byte[] buffer = new byte[9];
-
- this.currentStream.Read(buffer, 0, buffer.Length);
-
- byte packed = buffer[8];
-
- GifImageDescriptor imageDescriptor = new GifImageDescriptor
- {
- Left = BitConverter.ToInt16(buffer, 0),
- Top = BitConverter.ToInt16(buffer, 2),
- Width = BitConverter.ToInt16(buffer, 4),
- Height = BitConverter.ToInt16(buffer, 6),
- LocalColorTableFlag = ((packed & 0x80) >> 7) == 1,
- LocalColorTableSize = 2 << (packed & 0x07),
- InterlaceFlag = ((packed & 0x40) >> 6) == 1
- };
-
- return imageDescriptor;
- }
-
- ///
- /// Reads the logical screen descriptor.
- ///
- private void ReadLogicalScreenDescriptor()
- {
- byte[] buffer = new byte[7];
-
- this.currentStream.Read(buffer, 0, buffer.Length);
-
- byte packed = buffer[4];
-
- this.logicalScreenDescriptor = new GifLogicalScreenDescriptor
- {
- Width = BitConverter.ToInt16(buffer, 0),
- Height = BitConverter.ToInt16(buffer, 2),
- BackgroundColorIndex = buffer[5],
- PixelAspectRatio = buffer[6],
- GlobalColorTableFlag = ((packed & 0x80) >> 7) == 1,
- GlobalColorTableSize = 2 << (packed & 0x07)
- };
-
- if (this.logicalScreenDescriptor.GlobalColorTableSize > 255 * 4)
- {
- throw new ImageFormatException(
- $"Invalid gif colormap size '{this.logicalScreenDescriptor.GlobalColorTableSize}'");
- }
-
- if (this.logicalScreenDescriptor.Width > ImageBase.MaxWidth || this.logicalScreenDescriptor.Height > ImageBase.MaxHeight)
- {
- throw new ArgumentOutOfRangeException(
- $"The input gif '{this.logicalScreenDescriptor.Width}x{this.logicalScreenDescriptor.Height}' is bigger then the max allowed size '{ImageBase.MaxWidth}x{ImageBase.MaxHeight}'");
- }
- }
-
- ///
- /// Skips the designated number of bytes in the stream.
- ///
- /// The number of bytes to skip.
- private void Skip(int length)
- {
- this.currentStream.Seek(length, SeekOrigin.Current);
-
- int flag;
-
- while ((flag = this.currentStream.ReadByte()) != 0)
- {
- this.currentStream.Seek(flag, SeekOrigin.Current);
- }
- }
-
- ///
- /// Reads the gif comments.
- ///
- private void ReadComments()
- {
- int flag;
-
- while ((flag = this.currentStream.ReadByte()) != 0)
- {
- if (flag > GifConstants.MaxCommentLength)
- {
- throw new ImageFormatException($"Gif comment length '{flag}' exceeds max '{GifConstants.MaxCommentLength}'");
- }
-
- byte[] buffer = new byte[flag];
-
- this.currentStream.Read(buffer, 0, flag);
-
- this.decodedImage.Properties.Add(new ImageProperty("Comments", BitConverter.ToString(buffer)));
- }
- }
-
- ///
- /// Reads an individual gif frame.
- ///
- private void ReadFrame()
- {
- GifImageDescriptor imageDescriptor = this.ReadImageDescriptor();
-
- byte[] localColorTable = this.ReadFrameLocalColorTable(imageDescriptor);
-
- byte[] indices = this.ReadFrameIndices(imageDescriptor);
-
- // Determine the color table for this frame. If there is a local one, use it
- // otherwise use the global color table.
- byte[] colorTable = localColorTable ?? this.globalColorTable;
-
- this.ReadFrameColors(indices, colorTable, imageDescriptor);
-
- // Skip any remaining blocks
- this.Skip(0);
- }
-
- ///
- /// Reads the frame indices marking the color to use for each pixel.
- ///
- /// The .
- /// The
- private byte[] ReadFrameIndices(GifImageDescriptor imageDescriptor)
- {
- int dataSize = this.currentStream.ReadByte();
- LzwDecoder lzwDecoder = new LzwDecoder(this.currentStream);
-
- byte[] indices = lzwDecoder.DecodePixels(imageDescriptor.Width, imageDescriptor.Height, dataSize);
-
- return indices;
- }
-
- ///
- /// Reads the local color table from the current frame.
- ///
- /// The .
- /// The
- private byte[] ReadFrameLocalColorTable(GifImageDescriptor imageDescriptor)
- {
- byte[] localColorTable = null;
-
- if (imageDescriptor.LocalColorTableFlag)
- {
- localColorTable = new byte[imageDescriptor.LocalColorTableSize * 3];
-
- this.currentStream.Read(localColorTable, 0, localColorTable.Length);
- }
-
- return localColorTable;
- }
-
- ///
- /// Reads the frames colors, mapping indices to colors.
- ///
- /// The indexed pixels.
- /// The color table containing the available colors.
- /// The
- private void ReadFrameColors(byte[] indices, byte[] colorTable, GifImageDescriptor descriptor)
- {
- int imageWidth = this.logicalScreenDescriptor.Width;
- int imageHeight = this.logicalScreenDescriptor.Height;
-
- if (this.currentFrame == null)
- {
- this.currentFrame = new float[imageWidth * imageHeight * 4];
- }
-
- float[] lastFrame = null;
-
- if (this.graphicsControlExtension != null &&
- this.graphicsControlExtension.DisposalMethod == DisposalMethod.RestoreToPrevious)
- {
- lastFrame = new float[imageWidth * imageHeight * 4];
-
- Array.Copy(this.currentFrame, lastFrame, lastFrame.Length);
- }
-
- int offset, i = 0;
- int interlacePass = 0; // The interlace pass
- int interlaceIncrement = 8; // The interlacing line increment
- int interlaceY = 0; // The current interlaced line
-
- for (int y = descriptor.Top; y < descriptor.Top + descriptor.Height; y++)
- {
- // Check if this image is interlaced.
- int writeY; // the target y offset to write to
- if (descriptor.InterlaceFlag)
- {
- // If so then we read lines at predetermined offsets.
- // When an entire image height worth of offset lines has been read we consider this a pass.
- // With each pass the number of offset lines changes and the starting line changes.
- if (interlaceY >= descriptor.Height)
- {
- interlacePass++;
- switch (interlacePass)
- {
- case 1:
- interlaceY = 4;
- break;
- case 2:
- interlaceY = 2;
- interlaceIncrement = 4;
- break;
- case 3:
- interlaceY = 1;
- interlaceIncrement = 2;
- break;
- }
- }
-
- writeY = interlaceY + descriptor.Top;
-
- interlaceY += interlaceIncrement;
- }
- else
- {
- writeY = y;
- }
-
- for (int x = descriptor.Left; x < descriptor.Left + descriptor.Width; x++)
- {
- offset = ((writeY * imageWidth) + x) * 4;
- int index = indices[i];
-
- if (this.graphicsControlExtension == null ||
- this.graphicsControlExtension.TransparencyFlag == false ||
- this.graphicsControlExtension.TransparencyIndex != index)
- {
- // We divide by 255 as we will store the colors in our floating point format.
- // Stored in r-> g-> b-> a order.
- // Gifs don't store alpha transparency so we don't need to convert to
- // premultiplied.
- int indexOffset = index * 3;
- this.currentFrame[offset + 0] = colorTable[indexOffset] / 255f; // r
- this.currentFrame[offset + 1] = colorTable[indexOffset + 1] / 255f; // g
- this.currentFrame[offset + 2] = colorTable[indexOffset + 2] / 255f; // b
- this.currentFrame[offset + 3] = 1; // a
- }
-
- i++;
- }
- }
-
- float[] pixels = new float[imageWidth * imageHeight * 4];
-
- Array.Copy(this.currentFrame, pixels, pixels.Length);
-
- ImageBase currentImage;
-
- if (this.decodedImage.Pixels == null)
- {
- currentImage = this.decodedImage;
- currentImage.SetPixels(imageWidth, imageHeight, pixels);
- currentImage.Quality = colorTable.Length / 3;
-
- if (this.graphicsControlExtension != null && this.graphicsControlExtension.DelayTime > 0)
- {
- this.decodedImage.FrameDelay = this.graphicsControlExtension.DelayTime;
- }
- }
- else
- {
- ImageFrame frame = new ImageFrame();
-
- currentImage = frame;
- currentImage.SetPixels(imageWidth, imageHeight, pixels);
- currentImage.Quality = colorTable.Length / 3;
-
- if (this.graphicsControlExtension != null && this.graphicsControlExtension.DelayTime > 0)
- {
- currentImage.FrameDelay = this.graphicsControlExtension.DelayTime;
- }
-
- this.decodedImage.Frames.Add(frame);
- }
-
- if (this.graphicsControlExtension != null)
- {
- if (this.graphicsControlExtension.DisposalMethod == DisposalMethod.RestoreToBackground)
- {
- for (int y = descriptor.Top; y < descriptor.Top + descriptor.Height; y++)
- {
- for (int x = descriptor.Left; x < descriptor.Left + descriptor.Width; x++)
- {
- offset = ((y * imageWidth) + x) * 4;
-
- // Stored in r-> g-> b-> a order.
- this.currentFrame[offset] = 0;
- this.currentFrame[offset + 1] = 0;
- this.currentFrame[offset + 2] = 0;
- this.currentFrame[offset + 3] = 0;
- }
- }
- }
- else if (this.graphicsControlExtension.DisposalMethod == DisposalMethod.RestoreToPrevious)
- {
- this.currentFrame = lastFrame;
- }
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Gif/GifEncoder.cs b/src/ImageProcessorCore - Copy/Formats/Gif/GifEncoder.cs
deleted file mode 100644
index 7a1c81c2b7..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Gif/GifEncoder.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
-
- using ImageProcessorCore.Quantizers;
-
- ///
- /// Image encoder for writing image data to a stream in gif format.
- ///
- public class GifEncoder : IImageEncoder
- {
- ///
- /// Gets or sets the quality of output for images.
- ///
- /// For gifs the value ranges from 1 to 256.
- public int Quality { get; set; }
-
- ///
- /// Gets or sets the transparency threshold.
- ///
- public byte Threshold { get; set; } = 128;
-
- ///
- /// The quantizer for reducing the color count.
- ///
- public IQuantizer Quantizer { get; set; }
-
- ///
- public string Extension => "gif";
-
- ///
- public string MimeType => "image/gif";
-
- ///
- public bool IsSupportedFileExtension(string extension)
- {
- Guard.NotNullOrEmpty(extension, nameof(extension));
-
- extension = extension.StartsWith(".") ? extension.Substring(1) : extension;
- return extension.Equals(this.Extension, StringComparison.OrdinalIgnoreCase);
- }
-
- ///
- public void Encode(ImageBase image, Stream stream)
- {
- GifEncoderCore encoder = new GifEncoderCore
- {
- Quality = this.Quality,
- Quantizer = this.Quantizer,
- Threshold = this.Threshold
- };
-
- encoder.Encode(image, stream);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Gif/GifEncoderCore.cs b/src/ImageProcessorCore - Copy/Formats/Gif/GifEncoderCore.cs
deleted file mode 100644
index c4846c44f5..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Gif/GifEncoderCore.cs
+++ /dev/null
@@ -1,289 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
- using System.Linq;
- using System.Threading.Tasks;
-
- using ImageProcessorCore.IO;
- using ImageProcessorCore.Quantizers;
-
- ///
- /// Performs the gif encoding operation.
- ///
- internal sealed class GifEncoderCore
- {
- ///
- /// The number of bits requires to store the image palette.
- ///
- private int bitDepth;
-
- ///
- /// Gets or sets the quality of output for images.
- ///
- /// For gifs the value ranges from 1 to 256.
- public int Quality { get; set; }
-
- ///
- /// Gets or sets the transparency threshold.
- ///
- public byte Threshold { get; set; } = 128;
-
- ///
- /// The quantizer for reducing the color count.
- ///
- public IQuantizer Quantizer { get; set; }
-
- ///
- /// Encodes the image to the specified stream from the .
- ///
- /// The to encode from.
- /// The to encode the image data to.
- public void Encode(ImageBase imageBase, Stream stream)
- {
- Guard.NotNull(imageBase, nameof(imageBase));
- Guard.NotNull(stream, nameof(stream));
-
- Image image = (Image)imageBase;
-
- if (this.Quantizer == null)
- {
- this.Quantizer = new OctreeQuantizer { Threshold = this.Threshold };
- }
-
- // Do not use IDisposable pattern here as we want to preserve the stream.
- EndianBinaryWriter writer = new EndianBinaryWriter(EndianBitConverter.Little, stream);
-
- // Ensure that quality can be set but has a fallback.
- int quality = this.Quality > 0 ? this.Quality : imageBase.Quality;
- this.Quality = quality > 0 ? quality.Clamp(1, 256) : 256;
-
- // Get the number of bits.
- this.bitDepth = ImageMaths.GetBitsNeededForColorDepth(this.Quality);
-
- // Quantize the image returning a palette.
- QuantizedImage quantized = this.Quantizer.Quantize(image, this.Quality);
-
- // Write the header.
- this.WriteHeader(writer);
-
- // Write the LSD. We'll use local color tables for now.
- this.WriteLogicalScreenDescriptor(image, writer, quantized.TransparentIndex);
-
- // Write the first frame.
- this.WriteGraphicalControlExtension(imageBase, writer, quantized.TransparentIndex);
- this.WriteImageDescriptor(image, writer);
- this.WriteColorTable(quantized, writer);
- this.WriteImageData(quantized, writer);
-
- // Write additional frames.
- if (image.Frames.Any())
- {
- this.WriteApplicationExtension(writer, image.RepeatCount, image.Frames.Count);
- foreach (ImageFrame frame in image.Frames)
- {
- QuantizedImage quantizedFrame = this.Quantizer.Quantize(frame, this.Quality);
- this.WriteGraphicalControlExtension(frame, writer, quantizedFrame.TransparentIndex);
- this.WriteImageDescriptor(frame, writer);
- this.WriteColorTable(quantizedFrame, writer);
- this.WriteImageData(quantizedFrame, writer);
- }
- }
-
- // TODO: Write Comments extension etc
- writer.Write(GifConstants.EndIntroducer);
- }
-
- ///
- /// Writes the file header signature and version to the stream.
- ///
- /// The writer to write to the stream with.
- private void WriteHeader(EndianBinaryWriter writer)
- {
- writer.Write((GifConstants.FileType + GifConstants.FileVersion).ToCharArray());
- }
-
- ///
- /// Writes the logical screen descriptor to the stream.
- ///
- /// The image to encode.
- /// The writer to write to the stream with.
- /// The transparency index to set the default backgound index to.
- private void WriteLogicalScreenDescriptor(Image image, EndianBinaryWriter writer, int tranparencyIndex)
- {
- GifLogicalScreenDescriptor descriptor = new GifLogicalScreenDescriptor
- {
- Width = (short)image.Width,
- Height = (short)image.Height,
- GlobalColorTableFlag = false, // Always false for now.
- GlobalColorTableSize = this.bitDepth - 1,
- BackgroundColorIndex = (byte)(tranparencyIndex > -1 ? tranparencyIndex : 255)
- };
-
- writer.Write((ushort)descriptor.Width);
- writer.Write((ushort)descriptor.Height);
-
- PackedField field = new PackedField();
- field.SetBit(0, descriptor.GlobalColorTableFlag); // 1 : Global color table flag = 1 || 0 (GCT used/ not used)
- field.SetBits(1, 3, descriptor.GlobalColorTableSize); // 2-4 : color resolution
- field.SetBit(4, false); // 5 : GCT sort flag = 0
- field.SetBits(5, 3, descriptor.GlobalColorTableSize); // 6-8 : GCT size. 2^(N+1)
-
- // Reduce the number of writes
- byte[] arr = {
- field.Byte,
- descriptor.BackgroundColorIndex, // Background Color Index
- descriptor.PixelAspectRatio // Pixel aspect ratio. Assume 1:1
- };
-
- writer.Write(arr);
- }
-
- ///
- /// Writes the application exstension to the stream.
- ///
- /// The writer to write to the stream with.
- /// The animated image repeat count.
- /// Th number of image frames.
- private void WriteApplicationExtension(EndianBinaryWriter writer, ushort repeatCount, int frames)
- {
- // Application Extension Header
- if (repeatCount != 1 && frames > 0)
- {
- byte[] ext =
- {
- GifConstants.ExtensionIntroducer,
- GifConstants.ApplicationExtensionLabel,
- GifConstants.ApplicationBlockSize
- };
-
- writer.Write(ext);
-
- writer.Write(GifConstants.ApplicationIdentification.ToCharArray()); // NETSCAPE2.0
- writer.Write((byte)3); // Application block length
- writer.Write((byte)1); // Data sub-block index (always 1)
-
- // 0 means loop indefinitely. Count is set as play n + 1 times.
- repeatCount = (ushort)(Math.Max((ushort)0, repeatCount) - 1);
-
- writer.Write(repeatCount); // Repeat count for images.
-
- writer.Write(GifConstants.Terminator); // Terminator
- }
- }
-
- ///
- /// Writes the graphics control extension to the stream.
- ///
- /// The to encode.
- /// The stream to write to.
- /// The index of the color in the color palette to make transparent.
- private void WriteGraphicalControlExtension(ImageBase image, EndianBinaryWriter writer, int transparencyIndex)
- {
- // TODO: Check transparency logic.
- bool hasTransparent = transparencyIndex > -1;
- DisposalMethod disposalMethod = hasTransparent
- ? DisposalMethod.RestoreToBackground
- : DisposalMethod.Unspecified;
-
- GifGraphicsControlExtension extension = new GifGraphicsControlExtension()
- {
- DisposalMethod = disposalMethod,
- TransparencyFlag = hasTransparent,
- TransparencyIndex = transparencyIndex,
- DelayTime = image.FrameDelay
- };
-
- // Reduce the number of writes.
- byte[] intro = {
- GifConstants.ExtensionIntroducer,
- GifConstants.GraphicControlLabel,
- 4 // Size
- };
-
- writer.Write(intro);
-
- PackedField field = new PackedField();
- field.SetBits(3, 3, (int)extension.DisposalMethod); // 1-3 : Reserved, 4-6 : Disposal
-
- // TODO: Allow this as an option.
- field.SetBit(6, false); // 7 : User input - 0 = none
- field.SetBit(7, extension.TransparencyFlag); // 8: Has transparent.
-
- writer.Write(field.Byte);
- writer.Write((ushort)extension.DelayTime);
- writer.Write((byte)(extension.TransparencyIndex == -1 ? 255 : extension.TransparencyIndex));
- writer.Write(GifConstants.Terminator);
- }
-
- ///
- /// Writes the image descriptor to the stream.
- ///
- /// The to be encoded.
- /// The stream to write to.
- private void WriteImageDescriptor(ImageBase image, EndianBinaryWriter writer)
- {
- writer.Write(GifConstants.ImageDescriptorLabel); // 2c
- // TODO: Can we capture this?
- writer.Write((ushort)0); // Left position
- writer.Write((ushort)0); // Top position
- writer.Write((ushort)image.Width);
- writer.Write((ushort)image.Height);
-
- PackedField field = new PackedField();
- field.SetBit(0, true); // 1: Local color table flag = 1 (LCT used)
- field.SetBit(1, false); // 2: Interlace flag 0
- field.SetBit(2, false); // 3: Sort flag 0
- field.SetBits(5, 3, this.bitDepth - 1); // 4-5: Reserved, 6-8 : LCT size. 2^(N+1)
-
- writer.Write(field.Byte);
- }
-
- ///
- /// Writes the color table to the stream.
- ///
- /// The to encode.
- /// The writer to write to the stream with.
- private void WriteColorTable(QuantizedImage image, EndianBinaryWriter writer)
- {
- // Grab the palette and write it to the stream.
- Bgra32[] palette = image.Palette;
- int pixelCount = palette.Length;
-
- // Get max colors for bit depth.
- int colorTableLength = (int)Math.Pow(2, this.bitDepth) * 3;
- byte[] colorTable = new byte[colorTableLength];
-
- Parallel.For(0, pixelCount,
- i =>
- {
- int offset = i * 3;
- Bgra32 color = palette[i];
-
- colorTable[offset] = color.R;
- colorTable[offset + 1] = color.G;
- colorTable[offset + 2] = color.B;
- });
-
- writer.Write(colorTable, 0, colorTableLength);
- }
-
- ///
- /// Writes the image pixel data to the stream.
- ///
- /// The containing indexed pixels.
- /// The stream to write to.
- private void WriteImageData(QuantizedImage image, EndianBinaryWriter writer)
- {
- byte[] indexedPixels = image.Pixels;
-
- LzwEncoder encoder = new LzwEncoder(indexedPixels, (byte)this.bitDepth);
- encoder.Encode(writer.BaseStream);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Gif/GifFormat.cs b/src/ImageProcessorCore - Copy/Formats/Gif/GifFormat.cs
deleted file mode 100644
index 572815630f..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Gif/GifFormat.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Encapsulates the means to encode and decode gif images.
- ///
- public class GifFormat : IImageFormat
- {
- ///
- public IImageDecoder Decoder => new GifDecoder();
-
- ///
- public IImageEncoder Encoder => new GifEncoder();
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Gif/LzwDecoder.cs b/src/ImageProcessorCore - Copy/Formats/Gif/LzwDecoder.cs
deleted file mode 100644
index 75d590673a..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Gif/LzwDecoder.cs
+++ /dev/null
@@ -1,231 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
-
- ///
- /// Decompresses and decodes data using the dynamic LZW algorithms.
- ///
- internal sealed class LzwDecoder
- {
- ///
- /// The max decoder pixel stack size.
- ///
- private const int MaxStackSize = 4096;
-
- ///
- /// The null code.
- ///
- private const int NullCode = -1;
-
- ///
- /// The stream to decode.
- ///
- private readonly Stream stream;
-
- ///
- /// Initializes a new instance of the class
- /// and sets the stream, where the compressed data should be read from.
- ///
- /// The stream to read from.
- /// is null.
- public LzwDecoder(Stream stream)
- {
- Guard.NotNull(stream, nameof(stream));
-
- this.stream = stream;
- }
-
- ///
- /// Decodes and decompresses all pixel indices from the stream.
- ///
- ///
- ///
- /// The width of the pixel index array.
- /// The height of the pixel index array.
- /// Size of the data.
- /// The decoded and uncompressed array.
- public byte[] DecodePixels(int width, int height, int dataSize)
- {
- Guard.MustBeLessThan(dataSize, int.MaxValue, nameof(dataSize));
-
- // The resulting index table.
- byte[] pixels = new byte[width * height];
-
- // Calculate the clear code. The value of the clear code is 2 ^ dataSize
- int clearCode = 1 << dataSize;
-
- int codeSize = dataSize + 1;
-
- // Calculate the end code
- int endCode = clearCode + 1;
-
- // Calculate the available code.
- int availableCode = clearCode + 2;
-
- // Jillzhangs Code see: http://giflib.codeplex.com/
- // Adapted from John Cristy's ImageMagick.
- int code;
- int oldCode = NullCode;
- int codeMask = (1 << codeSize) - 1;
- int bits = 0;
-
- int[] prefix = new int[MaxStackSize];
- int[] suffix = new int[MaxStackSize];
- int[] pixelStatck = new int[MaxStackSize + 1];
-
- int top = 0;
- int count = 0;
- int bi = 0;
- int xyz = 0;
-
- int data = 0;
- int first = 0;
-
- for (code = 0; code < clearCode; code++)
- {
- prefix[code] = 0;
- suffix[code] = (byte)code;
- }
-
- byte[] buffer = null;
- while (xyz < pixels.Length)
- {
- if (top == 0)
- {
- if (bits < codeSize)
- {
- // Load bytes until there are enough bits for a code.
- if (count == 0)
- {
- // Read a new data block.
- buffer = this.ReadBlock();
- count = buffer.Length;
- if (count == 0)
- {
- break;
- }
-
- bi = 0;
- }
-
- if (buffer != null)
- {
- data += buffer[bi] << bits;
- }
-
- bits += 8;
- bi++;
- count--;
- continue;
- }
-
- // Get the next code
- code = data & codeMask;
- data >>= codeSize;
- bits -= codeSize;
-
- // Interpret the code
- if (code > availableCode || code == endCode)
- {
- break;
- }
-
- if (code == clearCode)
- {
- // Reset the decoder
- codeSize = dataSize + 1;
- codeMask = (1 << codeSize) - 1;
- availableCode = clearCode + 2;
- oldCode = NullCode;
- continue;
- }
-
- if (oldCode == NullCode)
- {
- pixelStatck[top++] = suffix[code];
- oldCode = code;
- first = code;
- continue;
- }
-
- int inCode = code;
- if (code == availableCode)
- {
- pixelStatck[top++] = (byte)first;
-
- code = oldCode;
- }
-
- while (code > clearCode)
- {
- pixelStatck[top++] = suffix[code];
- code = prefix[code];
- }
-
- first = suffix[code];
-
- pixelStatck[top++] = suffix[code];
-
- // Fix for Gifs that have "deferred clear code" as per here :
- // https://bugzilla.mozilla.org/show_bug.cgi?id=55918
- if (availableCode < MaxStackSize)
- {
- prefix[availableCode] = oldCode;
- suffix[availableCode] = first;
- availableCode++;
- if (availableCode == codeMask + 1 && availableCode < MaxStackSize)
- {
- codeSize++;
- codeMask = (1 << codeSize) - 1;
- }
- }
-
- oldCode = inCode;
- }
-
- // Pop a pixel off the pixel stack.
- top--;
-
- // Clear missing pixels
- pixels[xyz++] = (byte)pixelStatck[top];
- }
-
- return pixels;
- }
-
- ///
- /// Reads the next data block from the stream. A data block begins with a byte,
- /// which defines the size of the block, followed by the block itself.
- ///
- ///
- /// The .
- ///
- private byte[] ReadBlock()
- {
- int blockSize = this.stream.ReadByte();
- return this.ReadBytes(blockSize);
- }
-
- ///
- /// Reads the specified number of bytes from the data stream.
- ///
- ///
- /// The number of bytes to read.
- ///
- ///
- /// The .
- ///
- private byte[] ReadBytes(int length)
- {
- byte[] buffer = new byte[length];
- this.stream.Read(buffer, 0, length);
- return buffer;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Gif/LzwEncoder.cs b/src/ImageProcessorCore - Copy/Formats/Gif/LzwEncoder.cs
deleted file mode 100644
index a9681d2c56..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Gif/LzwEncoder.cs
+++ /dev/null
@@ -1,385 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
-
- ///
- /// Encodes and compresses the image data using dynamic Lempel-Ziv compression.
- ///
- ///
- /// Adapted from Jef Poskanzer's Java port by way of J. M. G. Elliott. K Weiner 12/00
- ///
- /// GIFCOMPR.C - GIF Image compression routines
- ///
- /// Lempel-Ziv compression based on 'compress'. GIF modifications by
- /// David Rowley (mgardi@watdcsu.waterloo.edu)
- ///
- ///
- /// GIF Image compression - modified 'compress'
- ///
- /// Based on: compress.c - File compression ala IEEE Computer, June 1984.
- ///
- /// By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
- /// Jim McKie (decvax!mcvax!jim)
- /// Steve Davies (decvax!vax135!petsd!peora!srd)
- /// Ken Turkowski (decvax!decwrl!turtlevax!ken)
- /// James A. Woods (decvax!ihnp4!ames!jaw)
- /// Joe Orost (decvax!vax135!petsd!joe)
- ///
- ///
- internal sealed class LzwEncoder
- {
- private const int Eof = -1;
-
- private const int Bits = 12;
-
- private const int HashSize = 5003; // 80% occupancy
-
- private readonly byte[] pixelArray;
-
- private readonly int initialCodeSize;
-
- private int curPixel;
-
- ///
- /// Number of bits/code
- ///
- private int bitCount;
-
- ///
- /// User settable max # bits/code
- ///
- private int maxbits = Bits;
-
- private int maxcode; // maximum code, given bitCount
-
- private int maxmaxcode = 1 << Bits; // should NEVER generate this code
-
- private readonly int[] hashTable = new int[HashSize];
-
- private readonly int[] codeTable = new int[HashSize];
-
- ///
- /// For dynamic table sizing
- ///
- private int hsize = HashSize;
-
- ///
- /// First unused entry
- ///
- private int freeEntry;
-
- ///
- /// Block compression parameters -- after all codes are used up,
- /// and compression rate changes, start over.
- ///
- private bool clearFlag;
-
- // Algorithm: use open addressing double hashing (no chaining) on the
- // prefix code / next character combination. We do a variant of Knuth's
- // algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
- // secondary probe. Here, the modular division first probe is gives way
- // to a faster exclusive-or manipulation. Also do block compression with
- // an adaptive reset, whereby the code table is cleared when the compression
- // ratio decreases, but after the table fills. The variable-length output
- // codes are re-sized at this point, and a special CLEAR code is generated
- // for the decompressor. Late addition: construct the table according to
- // file size for noticeable speed improvement on small files. Please direct
- // questions about this implementation to ames!jaw.
-
- private int globalInitialBits;
-
- private int clearCode;
-
- private int eofCode;
-
- // output
- //
- // Output the given code.
- // Inputs:
- // code: A bitCount-bit integer. If == -1, then EOF. This assumes
- // that bitCount =< wordsize - 1.
- // Outputs:
- // Outputs code to the file.
- // Assumptions:
- // Chars are 8 bits long.
- // Algorithm:
- // Maintain a BITS character long buffer (so that 8 codes will
- // fit in it exactly). Use the VAX insv instruction to insert each
- // code in turn. When the buffer fills up empty it and start over.
-
- private int currentAccumulator;
-
- private int currentBits;
-
- private readonly int[] masks =
- {
- 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF,
- 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
- };
-
- ///
- /// Number of characters so far in this 'packet'
- ///
- private int accumulatorCount;
-
- ///
- /// Define the storage for the packet accumulator.
- ///
- private readonly byte[] accumulators = new byte[256];
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The array of indexed pixels.
- /// The color depth in bits.
- public LzwEncoder(byte[] indexedPixels, int colorDepth)
- {
- this.pixelArray = indexedPixels;
- this.initialCodeSize = Math.Max(2, colorDepth);
- }
-
- ///
- /// Encodes and compresses the indexed pixels to the stream.
- ///
- /// The stream to write to.
- public void Encode(Stream stream)
- {
- // Write "initial code size" byte
- stream.WriteByte((byte)this.initialCodeSize);
-
- this.curPixel = 0;
-
- // Compress and write the pixel data
- this.Compress(this.initialCodeSize + 1, stream);
-
- // Write block terminator
- stream.WriteByte(GifConstants.Terminator);
- }
-
- ///
- /// Gets the maximum code value
- ///
- /// The number of bits
- /// See
- private static int GetMaxcode(int bitCount)
- {
- return (1 << bitCount) - 1;
- }
-
- ///
- /// Add a character to the end of the current packet, and if it is 254 characters,
- /// flush the packet to disk.
- ///
- /// The character to add.
- /// The stream to write to.
- private void AddCharacter(byte c, Stream stream)
- {
- this.accumulators[this.accumulatorCount++] = c;
- if (this.accumulatorCount >= 254)
- {
- this.FlushPacket(stream);
- }
- }
-
- ///
- /// Table clear for block compress
- ///
- /// The output stream.
- private void ClearBlock(Stream stream)
- {
- this.ResetCodeTable(this.hsize);
- this.freeEntry = this.clearCode + 2;
- this.clearFlag = true;
-
- this.Output(this.clearCode, stream);
- }
-
- ///
- /// Reset the code table.
- ///
- /// The hash size.
- private void ResetCodeTable(int size)
- {
- for (int i = 0; i < size; ++i)
- {
- this.hashTable[i] = -1;
- }
- }
-
- ///
- /// Compress the packets to the stream.
- ///
- /// The inital bits.
- /// The stream to write to.
- private void Compress(int intialBits, Stream stream)
- {
- int fcode;
- int c;
- int ent;
- int hsizeReg;
- int hshift;
-
- // Set up the globals: globalInitialBits - initial number of bits
- this.globalInitialBits = intialBits;
-
- // Set up the necessary values
- this.clearFlag = false;
- this.bitCount = this.globalInitialBits;
- this.maxcode = GetMaxcode(this.bitCount);
-
- this.clearCode = 1 << (intialBits - 1);
- this.eofCode = this.clearCode + 1;
- this.freeEntry = this.clearCode + 2;
-
- this.accumulatorCount = 0; // clear packet
-
- ent = this.NextPixel();
-
- hshift = 0;
- for (fcode = this.hsize; fcode < 65536; fcode *= 2) { ++hshift; }
- hshift = 8 - hshift; // set hash code range bound
-
- hsizeReg = this.hsize;
-
- this.ResetCodeTable(hsizeReg); // clear hash table
-
- this.Output(this.clearCode, stream);
-
- while ((c = this.NextPixel()) != Eof)
- {
- fcode = (c << this.maxbits) + ent;
- int i = (c << hshift) ^ ent /* = 0 */;
-
- if (this.hashTable[i] == fcode)
- {
- ent = this.codeTable[i];
- continue;
- }
-
- // Non-empty slot
- if (this.hashTable[i] >= 0)
- {
- int disp = hsizeReg - i;
- if (i == 0) disp = 1;
- do
- {
- if ((i -= disp) < 0) { i += hsizeReg; }
-
- if (this.hashTable[i] == fcode)
- {
- ent = this.codeTable[i];
- break;
- }
- }
- while (this.hashTable[i] >= 0);
-
- if (this.hashTable[i] == fcode) { continue; }
- }
-
- this.Output(ent, stream);
- ent = c;
- if (this.freeEntry < this.maxmaxcode)
- {
- this.codeTable[i] = this.freeEntry++; // code -> hashtable
- this.hashTable[i] = fcode;
- }
- else this.ClearBlock(stream);
- }
-
- // Put out the final code.
- this.Output(ent, stream);
-
- this.Output(this.eofCode, stream);
- }
-
- // Flush the packet to disk, and reset the accumulator
- private void FlushPacket(Stream outs)
- {
- if (this.accumulatorCount > 0)
- {
- outs.WriteByte((byte)this.accumulatorCount);
- outs.Write(this.accumulators, 0, this.accumulatorCount);
- this.accumulatorCount = 0;
- }
- }
-
- ///
- /// Return the next pixel from the image
- ///
- ///
- /// The
- ///
- private int NextPixel()
- {
- if (this.curPixel == this.pixelArray.Length)
- {
- return Eof;
- }
-
- if (this.curPixel == this.pixelArray.Length)
- return Eof;
-
- this.curPixel++;
- return this.pixelArray[this.curPixel - 1] & 0xff;
- }
-
- ///
- /// Output the current code to the stream.
- ///
- /// The code.
- /// The stream to write to.
- private void Output(int code, Stream outs)
- {
- this.currentAccumulator &= this.masks[this.currentBits];
-
- if (this.currentBits > 0) this.currentAccumulator |= (code << this.currentBits);
- else this.currentAccumulator = code;
-
- this.currentBits += this.bitCount;
-
- while (this.currentBits >= 8)
- {
- this.AddCharacter((byte)(this.currentAccumulator & 0xff), outs);
- this.currentAccumulator >>= 8;
- this.currentBits -= 8;
- }
-
- // If the next entry is going to be too big for the code size,
- // then increase it, if possible.
- if (this.freeEntry > this.maxcode || this.clearFlag)
- {
- if (this.clearFlag)
- {
- this.maxcode = GetMaxcode(this.bitCount = this.globalInitialBits);
- this.clearFlag = false;
- }
- else
- {
- ++this.bitCount;
- this.maxcode = this.bitCount == this.maxbits
- ? this.maxmaxcode
- : GetMaxcode(this.bitCount);
- }
- }
-
- if (code == this.eofCode)
- {
- // At EOF, write the rest of the buffer.
- while (this.currentBits > 0)
- {
- this.AddCharacter((byte)(this.currentAccumulator & 0xff), outs);
- this.currentAccumulator >>= 8;
- this.currentBits -= 8;
- }
-
- this.FlushPacket(outs);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/Formats/Gif/PackedField.cs b/src/ImageProcessorCore - Copy/Formats/Gif/PackedField.cs
deleted file mode 100644
index 0141d36c6a..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Gif/PackedField.cs
+++ /dev/null
@@ -1,194 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
-
- ///
- /// Represents a byte of data in a GIF data stream which contains a number
- /// of data items.
- ///
- internal struct PackedField : IEquatable
- {
- ///
- /// The individual bits representing the packed byte.
- ///
- private static readonly bool[] Bits = new bool[8];
-
- ///
- /// Gets the byte which represents the data items held in this instance.
- ///
- public byte Byte
- {
- get
- {
- int returnValue = 0;
- int bitShift = 7;
- foreach (bool bit in Bits)
- {
- int bitValue;
- if (bit)
- {
- bitValue = 1 << bitShift;
- }
- else
- {
- bitValue = 0;
- }
- returnValue |= bitValue;
- bitShift--;
- }
- return Convert.ToByte(returnValue & 0xFF);
- }
- }
-
- ///
- /// Returns a new with the bits in the packed fields to
- /// the corresponding bits from the supplied byte.
- ///
- /// The value to pack.
- /// The
- public static PackedField FromInt(byte value)
- {
- PackedField packed = new PackedField();
- packed.SetBits(0, 8, value);
- return packed;
- }
-
- ///
- /// Sets the specified bit within the packed fields to the supplied
- /// value.
- ///
- ///
- /// The zero-based index within the packed fields of the bit to set.
- ///
- ///
- /// The value to set the bit to.
- ///
- public void SetBit(int index, bool valueToSet)
- {
- if (index < 0 || index > 7)
- {
- string message
- = "Index must be between 0 and 7. Supplied index: "
- + index;
- throw new ArgumentOutOfRangeException(nameof(index), message);
- }
- Bits[index] = valueToSet;
- }
-
- ///
- /// Sets the specified bits within the packed fields to the supplied
- /// value.
- ///
- /// The zero-based index within the packed fields of the first bit to set.
- /// The number of bits to set.
- /// The value to set the bits to.
- public void SetBits(int startIndex, int length, int valueToSet)
- {
- if (startIndex < 0 || startIndex > 7)
- {
- string message = $"Start index must be between 0 and 7. Supplied index: {startIndex}";
- throw new ArgumentOutOfRangeException(nameof(startIndex), message);
- }
-
- if (length < 1 || startIndex + length > 8)
- {
- string message = "Length must be greater than zero and the sum of length and start index must be less than 8. "
- + $"Supplied length: {length}. Supplied start index: {startIndex}";
- throw new ArgumentOutOfRangeException(nameof(length), message);
- }
-
- int bitShift = length - 1;
- for (int i = startIndex; i < startIndex + length; i++)
- {
- int bitValueIfSet = (1 << bitShift);
- int bitValue = (valueToSet & bitValueIfSet);
- int bitIsSet = (bitValue >> bitShift);
- Bits[i] = (bitIsSet == 1);
- bitShift--;
- }
- }
-
- ///
- /// Gets the value of the specified bit within the byte.
- ///
- /// The zero-based index of the bit to get.
- ///
- /// The value of the specified bit within the byte.
- ///
- public bool GetBit(int index)
- {
- if (index < 0 || index > 7)
- {
- string message = $"Index must be between 0 and 7. Supplied index: {index}";
- throw new ArgumentOutOfRangeException(nameof(index), message);
- }
- return Bits[index];
- }
-
- ///
- /// Gets the value of the specified bits within the byte.
- ///
- /// The zero-based index of the first bit to get.
- /// The number of bits to get.
- ///
- /// The value of the specified bits within the byte.
- ///
- public int GetBits(int startIndex, int length)
- {
- if (startIndex < 0 || startIndex > 7)
- {
- string message = $"Start index must be between 0 and 7. Supplied index: {startIndex}";
- throw new ArgumentOutOfRangeException(nameof(startIndex), message);
- }
-
- if (length < 1 || startIndex + length > 8)
- {
- string message = "Length must be greater than zero and the sum of length and start index must be less than 8. "
- + $"Supplied length: {length}. Supplied start index: {startIndex}";
-
- throw new ArgumentOutOfRangeException(nameof(length), message);
- }
-
- int returnValue = 0;
- int bitShift = length - 1;
- for (int i = startIndex; i < startIndex + length; i++)
- {
- int bitValue = (Bits[i] ? 1 : 0) << bitShift;
- returnValue += bitValue;
- bitShift--;
- }
- return returnValue;
- }
-
- ///
- public override bool Equals(object obj)
- {
- PackedField? field = obj as PackedField?;
-
- return this.Byte == field?.Byte;
- }
-
- ///
- public bool Equals(PackedField other)
- {
- return this.Byte.Equals(other.Byte);
- }
-
- ///
- public override string ToString()
- {
- return $"PackedField [ Byte={this.Byte} ]";
- }
-
- ///
- public override int GetHashCode()
- {
- return this.Byte.GetHashCode();
- }
- }
-}
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/Formats/Gif/README.md b/src/ImageProcessorCore - Copy/Formats/Gif/README.md
deleted file mode 100644
index d47a4c6836..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Gif/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-Encoder/Decoder adapted and extended from:
-
-https://github.com/yufeih/Nine.Imaging/
-https://imagetools.codeplex.com/
diff --git a/src/ImageProcessorCore - Copy/Formats/Gif/Sections/GifGraphicsControlExtension.cs b/src/ImageProcessorCore - Copy/Formats/Gif/Sections/GifGraphicsControlExtension.cs
deleted file mode 100644
index 071dc62c84..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Gif/Sections/GifGraphicsControlExtension.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// The Graphic Control Extension contains parameters used when
- /// processing a graphic rendering block.
- ///
- internal sealed class GifGraphicsControlExtension
- {
- ///
- /// Gets or sets the disposal method which indicates the way in which the
- /// graphic is to be treated after being displayed.
- ///
- public DisposalMethod DisposalMethod { get; set; }
-
- ///
- /// Gets or sets a value indicating whether transparency flag is to be set.
- /// This indicates whether a transparency index is given in the Transparent Index field.
- /// (This field is the least significant bit of the byte.)
- ///
- public bool TransparencyFlag { get; set; }
-
- ///
- /// Gets or sets the transparency index.
- /// The Transparency Index is such that when encountered, the corresponding pixel
- /// of the display device is not modified and processing goes on to the next pixel.
- ///
- public int TransparencyIndex { get; set; }
-
- ///
- /// Gets or sets the delay time.
- /// 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 DelayTime { get; set; }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Gif/Sections/GifImageDescriptor.cs b/src/ImageProcessorCore - Copy/Formats/Gif/Sections/GifImageDescriptor.cs
deleted file mode 100644
index 62737de660..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Gif/Sections/GifImageDescriptor.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Each image in the Data Stream is composed of an Image Descriptor,
- /// an optional Local Color Table, and the image data.
- /// Each image must fit within the boundaries of the
- /// Logical Screen, as defined in the Logical Screen Descriptor.
- ///
- internal sealed class GifImageDescriptor
- {
- ///
- /// Gets or sets the column number, in pixels, of the left edge of the image,
- /// with respect to the left edge of the Logical Screen.
- /// Leftmost column of the Logical Screen is 0.
- ///
- public short Left { get; set; }
-
- ///
- /// Gets or sets the row number, in pixels, of the top edge of the image with
- /// respect to the top edge of the Logical Screen.
- /// Top row of the Logical Screen is 0.
- ///
- public short Top { get; set; }
-
- ///
- /// Gets or sets the width of the image in pixels.
- ///
- public short Width { get; set; }
-
- ///
- /// Gets or sets the height of the image in pixels.
- ///
- public short Height { get; set; }
-
- ///
- /// Gets or sets a value indicating whether the presence of a Local Color Table immediately
- /// follows this Image Descriptor.
- ///
- public bool LocalColorTableFlag { get; set; }
-
- ///
- /// Gets or sets the local color table size.
- /// If the Local Color Table Flag is set to 1, the value in this field
- /// is used to calculate the number of bytes contained in the Local Color Table.
- ///
- public int LocalColorTableSize { get; set; }
-
- ///
- /// Gets or sets a value indicating whether the image is to be interlaced.
- /// An image is interlaced in a four-pass interlace pattern.
- ///
- public bool InterlaceFlag { get; set; }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Gif/Sections/GifLogicalScreenDescriptor.cs b/src/ImageProcessorCore - Copy/Formats/Gif/Sections/GifLogicalScreenDescriptor.cs
deleted file mode 100644
index 8c0400f24d..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Gif/Sections/GifLogicalScreenDescriptor.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// The Logical Screen Descriptor contains the parameters
- /// necessary to define the area of the display device
- /// within which the images will be rendered
- ///
- internal sealed class GifLogicalScreenDescriptor
- {
- ///
- /// Gets or sets the width, in pixels, of the Logical Screen where the images will
- /// be rendered in the displaying device.
- ///
- public short Width { get; set; }
-
- ///
- /// Gets or sets the height, in pixels, of the Logical Screen where the images will be
- /// rendered in the displaying device.
- ///
- public short Height { get; set; }
-
- ///
- /// Gets or sets the index at the Global Color Table for the Background Color.
- /// The Background Color is the color used for those
- /// pixels on the screen that are not covered by an image.
- ///
- public byte BackgroundColorIndex { get; set; }
-
- ///
- /// Gets or sets the pixel aspect ratio. Default to 0.
- ///
- public byte PixelAspectRatio { get; set; }
-
- ///
- /// Gets or sets a value indicating whether a flag denoting the presence of a Global Color Table
- /// should be set.
- /// If the flag is set, the Global Color Table will immediately
- /// follow the Logical Screen Descriptor.
- ///
- public bool GlobalColorTableFlag { get; set; }
-
- ///
- /// Gets or sets the global color table size.
- /// If the Global Color Table Flag is set to 1,
- /// the value in this field is used to calculate the number of
- /// bytes contained in the Global Color Table.
- ///
- public int GlobalColorTableSize { get; set; }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/IImageDecoder.cs b/src/ImageProcessorCore - Copy/Formats/IImageDecoder.cs
deleted file mode 100644
index 0f3a8504c9..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/IImageDecoder.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System.IO;
-
- ///
- /// Encapsulates properties and methods required for decoding an image from a stream.
- ///
- public interface IImageDecoder
- {
- ///
- /// Gets the size of the header for this image type.
- ///
- /// The size of the header.
- int HeaderSize { get; }
-
- ///
- /// Returns a value indicating whether the supports the specified
- /// file header.
- ///
- /// The containing the file extension.
- ///
- /// True if the decoder supports the file extension; otherwise, false.
- ///
- bool IsSupportedFileExtension(string extension);
-
- ///
- /// Returns a value indicating whether the supports the specified
- /// file header.
- ///
- /// The containing the file header.
- ///
- /// True if the decoder supports the file header; otherwise, false.
- ///
- bool IsSupportedFileFormat(byte[] header);
-
- ///
- /// Decodes the image from the specified stream to the .
- ///
- /// The type of pixels contained within the image.
- /// The to decode to.
- /// The containing image data.
- void Decode(Image image, Stream stream) where TPackedVector : IPackedVector;
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/IImageEncoder.cs b/src/ImageProcessorCore - Copy/Formats/IImageEncoder.cs
deleted file mode 100644
index df7234aad0..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/IImageEncoder.cs
+++ /dev/null
@@ -1,53 +0,0 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-//
-// Encapsulates properties and methods required for decoding an image to a stream.
-//
-// --------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore.Formats
-{
- using System.IO;
-
- ///
- /// Encapsulates properties and methods required for encoding an image to a stream.
- ///
- public interface IImageEncoder
- {
- ///
- /// Gets or sets the quality of output for images.
- ///
- int Quality { get; set; }
-
- ///
- /// Gets the standard identifier used on the Internet to indicate the type of data that a file contains.
- ///
- string MimeType { get; }
-
- ///
- /// Gets the default file extension for this encoder.
- ///
- string Extension { get; }
-
- ///
- /// Returns a value indicating whether the supports the specified
- /// file header.
- ///
- /// The containing the file extension.
- ///
- /// True if the decoder supports the file extension; otherwise, false.
- ///
- bool IsSupportedFileExtension(string extension);
-
- ///
- /// Encodes the image to the specified stream from the .
- ///
- /// The type of pixels contained within the image.
- /// The to encode from.
- /// The to encode the image data to.
- void Encode(ImageBase image, Stream stream) where TPackedVector : IPackedVector;
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/IImageFormat.cs b/src/ImageProcessorCore - Copy/Formats/IImageFormat.cs
deleted file mode 100644
index 62b4b78916..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/IImageFormat.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Encapsulates a supported image format, providing means to encode and decode an image.
- ///
- public interface IImageFormat
- {
- ///
- /// Gets the image encoder for encoding an image from a stream.
- ///
- IImageEncoder Encoder { get; }
-
- ///
- /// Gets the image decoder for decoding an image from a stream.
- ///
- IImageDecoder Decoder { get; }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Jpg/Block.cs b/src/ImageProcessorCore - Copy/Formats/Jpg/Block.cs
deleted file mode 100644
index 35aa10f181..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Jpg/Block.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Represents an 8x8 block of coefficients to transform and encode.
- ///
- internal class Block
- {
- ///
- /// Gets the size of the block.
- ///
- public const int BlockSize = 64;
-
- ///
- /// The array of block data.
- ///
- private readonly int[] data;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public Block()
- {
- this.data = new int[BlockSize];
- }
-
- ///
- /// Gets the pixel data at the given block index.
- ///
- /// The index of the data to return.
- ///
- /// The .
- ///
- public int this[int index]
- {
- get { return this.data[index]; }
- set { this.data[index] = value; }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Jpg/FDCT.cs b/src/ImageProcessorCore - Copy/Formats/Jpg/FDCT.cs
deleted file mode 100644
index e51ea64151..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Jpg/FDCT.cs
+++ /dev/null
@@ -1,161 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Performs a fast, forward descrete cosine transform against the given block
- /// decomposing it into 64 orthogonal basis signals.
- ///
- internal class FDCT
- {
- // Trigonometric constants in 13-bit fixed point format.
- // TODO: Rename and describe these.
- private const int fix_0_298631336 = 2446;
- private const int fix_0_390180644 = 3196;
- private const int fix_0_541196100 = 4433;
- private const int fix_0_765366865 = 6270;
- private const int fix_0_899976223 = 7373;
- private const int fix_1_175875602 = 9633;
- private const int fix_1_501321110 = 12299;
- private const int fix_1_847759065 = 15137;
- private const int fix_1_961570560 = 16069;
- private const int fix_2_053119869 = 16819;
- private const int fix_2_562915447 = 20995;
- private const int fix_3_072711026 = 25172;
-
- ///
- /// The number of bits
- ///
- private const int Bits = 13;
-
- ///
- /// The number of bits to shift by on the first pass.
- ///
- private const int Pass1Bits = 2;
-
- ///
- /// The value to shift by
- ///
- private const int CenterJSample = 128;
-
- ///
- /// Performs a forward DCT on an 8x8 block of coefficients, including a
- /// level shift.
- ///
- /// The block.
- public static void Transform(Block block)
- {
- // Pass 1: process rows.
- for (int y = 0; y < 8; y++)
- {
- int y8 = y * 8;
-
- int x0 = block[y8];
- int x1 = block[y8 + 1];
- int x2 = block[y8 + 2];
- int x3 = block[y8 + 3];
- int x4 = block[y8 + 4];
- int x5 = block[y8 + 5];
- int x6 = block[y8 + 6];
- int x7 = block[y8 + 7];
-
- int tmp0 = x0 + x7;
- int tmp1 = x1 + x6;
- int tmp2 = x2 + x5;
- int tmp3 = x3 + x4;
-
- int tmp10 = tmp0 + tmp3;
- int tmp12 = tmp0 - tmp3;
- int tmp11 = tmp1 + tmp2;
- int tmp13 = tmp1 - tmp2;
-
- tmp0 = x0 - x7;
- tmp1 = x1 - x6;
- tmp2 = x2 - x5;
- tmp3 = x3 - x4;
-
- block[y8] = (tmp10 + tmp11 - (8 * CenterJSample)) << Pass1Bits;
- block[y8 + 4] = (tmp10 - tmp11) << Pass1Bits;
- int z1 = (tmp12 + tmp13) * fix_0_541196100;
- z1 += 1 << (Bits - Pass1Bits - 1);
- block[y8 + 2] = (z1 + (tmp12 * fix_0_765366865)) >> (Bits - Pass1Bits);
- block[y8 + 6] = (z1 - (tmp13 * fix_1_847759065)) >> (Bits - Pass1Bits);
-
- tmp10 = tmp0 + tmp3;
- tmp11 = tmp1 + tmp2;
- tmp12 = tmp0 + tmp2;
- tmp13 = tmp1 + tmp3;
- z1 = (tmp12 + tmp13) * fix_1_175875602;
- z1 += 1 << (Bits - Pass1Bits - 1);
- tmp0 = tmp0 * fix_1_501321110;
- tmp1 = tmp1 * fix_3_072711026;
- tmp2 = tmp2 * fix_2_053119869;
- tmp3 = tmp3 * fix_0_298631336;
- tmp10 = tmp10 * -fix_0_899976223;
- tmp11 = tmp11 * -fix_2_562915447;
- tmp12 = tmp12 * -fix_0_390180644;
- tmp13 = tmp13 * -fix_1_961570560;
-
- tmp12 += z1;
- tmp13 += z1;
- block[y8 + 1] = (tmp0 + tmp10 + tmp12) >> (Bits - Pass1Bits);
- block[y8 + 3] = (tmp1 + tmp11 + tmp13) >> (Bits - Pass1Bits);
- block[y8 + 5] = (tmp2 + tmp11 + tmp12) >> (Bits - Pass1Bits);
- block[y8 + 7] = (tmp3 + tmp10 + tmp13) >> (Bits - Pass1Bits);
- }
-
- // Pass 2: process columns.
- // We remove pass1Bits scaling, but leave results scaled up by an overall factor of 8.
- for (int x = 0; x < 8; x++)
- {
- int tmp0 = block[x] + block[56 + x];
- int tmp1 = block[8 + x] + block[48 + x];
- int tmp2 = block[16 + x] + block[40 + x];
- int tmp3 = block[24 + x] + block[32 + x];
-
- int tmp10 = tmp0 + tmp3 + (1 << (Pass1Bits - 1));
- int tmp12 = tmp0 - tmp3;
- int tmp11 = tmp1 + tmp2;
- int tmp13 = tmp1 - tmp2;
-
- tmp0 = block[x] - block[56 + x];
- tmp1 = block[8 + x] - block[48 + x];
- tmp2 = block[16 + x] - block[40 + x];
- tmp3 = block[24 + x] - block[32 + x];
-
- block[x] = (tmp10 + tmp11) >> Pass1Bits;
- block[32 + x] = (tmp10 - tmp11) >> Pass1Bits;
-
- int z1 = (tmp12 + tmp13) * fix_0_541196100;
- z1 += 1 << (Bits + Pass1Bits - 1);
- block[16 + x] = (z1 + (tmp12 * fix_0_765366865)) >> (Bits + Pass1Bits);
- block[48 + x] = (z1 - (tmp13 * fix_1_847759065)) >> (Bits + Pass1Bits);
-
- tmp10 = tmp0 + tmp3;
- tmp11 = tmp1 + tmp2;
- tmp12 = tmp0 + tmp2;
- tmp13 = tmp1 + tmp3;
- z1 = (tmp12 + tmp13) * fix_1_175875602;
- z1 += 1 << (Bits + Pass1Bits - 1);
- tmp0 = tmp0 * fix_1_501321110;
- tmp1 = tmp1 * fix_3_072711026;
- tmp2 = tmp2 * fix_2_053119869;
- tmp3 = tmp3 * fix_0_298631336;
- tmp10 = tmp10 * -fix_0_899976223;
- tmp11 = tmp11 * -fix_2_562915447;
- tmp12 = tmp12 * -fix_0_390180644;
- tmp13 = tmp13 * -fix_1_961570560;
-
- tmp12 += z1;
- tmp13 += z1;
- block[8 + x] = (tmp0 + tmp10 + tmp12) >> (Bits + Pass1Bits);
- block[24 + x] = (tmp1 + tmp11 + tmp13) >> (Bits + Pass1Bits);
- block[40 + x] = (tmp2 + tmp11 + tmp12) >> (Bits + Pass1Bits);
- block[56 + x] = (tmp3 + tmp10 + tmp13) >> (Bits + Pass1Bits);
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Jpg/IDCT.cs b/src/ImageProcessorCore - Copy/Formats/Jpg/IDCT.cs
deleted file mode 100644
index 7542f4d383..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Jpg/IDCT.cs
+++ /dev/null
@@ -1,163 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- internal class IDCT
- {
- private const int w1 = 2841; // 2048*sqrt(2)*cos(1*pi/16)
- private const int w2 = 2676; // 2048*sqrt(2)*cos(2*pi/16)
- private const int w3 = 2408; // 2048*sqrt(2)*cos(3*pi/16)
- private const int w5 = 1609; // 2048*sqrt(2)*cos(5*pi/16)
- private const int w6 = 1108; // 2048*sqrt(2)*cos(6*pi/16)
- private const int w7 = 565; // 2048*sqrt(2)*cos(7*pi/16)
-
- private const int w1pw7 = w1 + w7;
- private const int w1mw7 = w1 - w7;
- private const int w2pw6 = w2 + w6;
- private const int w2mw6 = w2 - w6;
- private const int w3pw5 = w3 + w5;
- private const int w3mw5 = w3 - w5;
-
- private const int r2 = 181; // 256/sqrt(2)
-
- // idct performs a 2-D Inverse Discrete Cosine Transformation.
- //
- // The input coefficients should already have been multiplied by the
- // appropriate quantization table. We use fixed-point computation, with the
- // number of bits for the fractional component varying over the intermediate
- // stages.
- //
- // For more on the actual algorithm, see Z. Wang, "Fast algorithms for the
- // discrete W transform and for the discrete Fourier transform", IEEE Trans. on
- // ASSP, Vol. ASSP- 32, pp. 803-816, Aug. 1984.
- public static void Transform(Block src)
- {
- // Horizontal 1-D IDCT.
- for (int y = 0; y < 8; y++)
- {
- int y8 = y * 8;
-
- // If all the AC components are zero, then the IDCT is trivial.
- if (src[y8 + 1] == 0 && src[y8 + 2] == 0 && src[y8 + 3] == 0 &&
- src[y8 + 4] == 0 && src[y8 + 5] == 0 && src[y8 + 6] == 0 && src[y8 + 7] == 0)
- {
- int dc = src[y8 + 0] << 3;
- src[y8 + 0] = dc;
- src[y8 + 1] = dc;
- src[y8 + 2] = dc;
- src[y8 + 3] = dc;
- src[y8 + 4] = dc;
- src[y8 + 5] = dc;
- src[y8 + 6] = dc;
- src[y8 + 7] = dc;
- continue;
- }
-
- // Prescale.
- int x0 = (src[y8 + 0] << 11) + 128;
- int x1 = src[y8 + 4] << 11;
- int x2 = src[y8 + 6];
- int x3 = src[y8 + 2];
- int x4 = src[y8 + 1];
- int x5 = src[y8 + 7];
- int x6 = src[y8 + 5];
- int x7 = src[y8 + 3];
-
- // Stage 1.
- int x8 = w7 * (x4 + x5);
- x4 = x8 + w1mw7 * x4;
- x5 = x8 - w1pw7 * x5;
- x8 = w3 * (x6 + x7);
- x6 = x8 - w3mw5 * x6;
- x7 = x8 - w3pw5 * x7;
-
- // Stage 2.
- x8 = x0 + x1;
- x0 -= x1;
- x1 = w6 * (x3 + x2);
- x2 = x1 - w2pw6 * x2;
- x3 = x1 + w2mw6 * x3;
- x1 = x4 + x6;
- x4 -= x6;
- x6 = x5 + x7;
- x5 -= x7;
-
- // Stage 3.
- x7 = x8 + x3;
- x8 -= x3;
- x3 = x0 + x2;
- x0 -= x2;
- x2 = (r2 * (x4 + x5) + 128) >> 8;
- x4 = (r2 * (x4 - x5) + 128) >> 8;
-
- // Stage 4.
- src[y8 + 0] = (x7 + x1) >> 8;
- src[y8 + 1] = (x3 + x2) >> 8;
- src[y8 + 2] = (x0 + x4) >> 8;
- src[y8 + 3] = (x8 + x6) >> 8;
- src[y8 + 4] = (x8 - x6) >> 8;
- src[y8 + 5] = (x0 - x4) >> 8;
- src[y8 + 6] = (x3 - x2) >> 8;
- src[y8 + 7] = (x7 - x1) >> 8;
- }
-
- // Vertical 1-D IDCT.
- for (int x = 0; x < 8; x++)
- {
- // Similar to the horizontal 1-D IDCT case, if all the AC components are zero, then the IDCT is trivial.
- // However, after performing the horizontal 1-D IDCT, there are typically non-zero AC components, so
- // we do not bother to check for the all-zero case.
-
- // Prescale.
- int y0 = (src[x] << 8) + 8192;
- int y1 = src[32 + x] << 8;
- int y2 = src[48 + x];
- int y3 = src[16 + x];
- int y4 = src[8 + x];
- int y5 = src[56 + x];
- int y6 = src[40 + x];
- int y7 = src[24 + x];
-
- // Stage 1.
- int y8 = w7 * (y4 + y5) + 4;
- y4 = (y8 + w1mw7 * y4) >> 3;
- y5 = (y8 - w1pw7 * y5) >> 3;
- y8 = w3 * (y6 + y7) + 4;
- y6 = (y8 - w3mw5 * y6) >> 3;
- y7 = (y8 - w3pw5 * y7) >> 3;
-
- // Stage 2.
- y8 = y0 + y1;
- y0 -= y1;
- y1 = w6 * (y3 + y2) + 4;
- y2 = (y1 - w2pw6 * y2) >> 3;
- y3 = (y1 + w2mw6 * y3) >> 3;
- y1 = y4 + y6;
- y4 -= y6;
- y6 = y5 + y7;
- y5 -= y7;
-
- // Stage 3.
- y7 = y8 + y3;
- y8 -= y3;
- y3 = y0 + y2;
- y0 -= y2;
- y2 = (r2 * (y4 + y5) + 128) >> 8;
- y4 = (r2 * (y4 - y5) + 128) >> 8;
-
- // Stage 4.
- src[x] = (y7 + y1) >> 14;
- src[8 + x] = (y3 + y2) >> 14;
- src[16 + x] = (y0 + y4) >> 14;
- src[24 + x] = (y8 + y6) >> 14;
- src[32 + x] = (y8 - y6) >> 14;
- src[40 + x] = (y0 - y4) >> 14;
- src[48 + x] = (y3 - y2) >> 14;
- src[56 + x] = (y7 - y1) >> 14;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Jpg/JpegDecoder.cs b/src/ImageProcessorCore - Copy/Formats/Jpg/JpegDecoder.cs
deleted file mode 100644
index 89aa4e0014..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Jpg/JpegDecoder.cs
+++ /dev/null
@@ -1,149 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
-
- ///
- /// Image decoder for generating an image out of a jpg stream.
- ///
- public class JpegDecoder : IImageDecoder
- {
- ///
- /// Gets the size of the header for this image type.
- ///
- /// The size of the header.
- public int HeaderSize => 11;
-
- ///
- /// Indicates if the image decoder supports the specified
- /// file extension.
- ///
- /// The file extension.
- ///
- /// true, if the decoder supports the specified
- /// extensions; otherwise false.
- ///
- ///
- /// is null (Nothing in Visual Basic).
- /// is a string
- /// of length zero or contains only blanks.
- public bool IsSupportedFileExtension(string extension)
- {
- Guard.NotNullOrEmpty(extension, "extension");
-
- if (extension.StartsWith("."))
- {
- extension = extension.Substring(1);
- }
-
- return extension.Equals("JPG", StringComparison.OrdinalIgnoreCase) ||
- extension.Equals("JPEG", StringComparison.OrdinalIgnoreCase) ||
- extension.Equals("JFIF", StringComparison.OrdinalIgnoreCase);
- }
-
- ///
- /// Indicates if the image decoder supports the specified
- /// file header.
- ///
- /// The file header.
- ///
- /// true, if the decoder supports the specified
- /// file header; otherwise false.
- ///
- ///
- /// is null (Nothing in Visual Basic).
- public bool IsSupportedFileFormat(byte[] header)
- {
- Guard.NotNull(header, "header");
-
- bool isSupported = false;
-
- if (header.Length >= 11)
- {
- bool isJfif = IsJfif(header);
- bool isExif = IsExif(header);
- bool isJpeg = IsJpeg(header);
-
- isSupported = isJfif || isExif || isJpeg;
- }
-
- return isSupported;
- }
-
- ///
- /// Decodes the image from the specified stream and sets
- /// the data to image.
- ///
- /// The image, where the data should be set to.
- /// Cannot be null (Nothing in Visual Basic).
- /// The stream, where the image should be
- /// decoded from. Cannot be null (Nothing in Visual Basic).
- ///
- /// is null (Nothing in Visual Basic).
- /// - or -
- /// is null (Nothing in Visual Basic).
- ///
- public void Decode(Image image, Stream stream)
- {
- Guard.NotNull(image, "image");
- Guard.NotNull(stream, "stream");
-
- JpegDecoderCore decoder = new JpegDecoderCore();
- decoder.Decode(stream, image, false);
- }
-
- ///
- /// Returns a value indicating whether the given bytes identify Jfif data.
- ///
- /// The bytes representing the file header.
- /// The
- private static bool IsJfif(byte[] header)
- {
- bool isJfif =
- header[6] == 0x4A && // J
- header[7] == 0x46 && // F
- header[8] == 0x49 && // I
- header[9] == 0x46 && // F
- header[10] == 0x00;
-
- return isJfif;
- }
-
- ///
- /// Returns a value indicating whether the given bytes identify EXIF data.
- ///
- /// The bytes representing the file header.
- /// The
- private static bool IsExif(byte[] header)
- {
- bool isExif =
- header[6] == 0x45 && // E
- header[7] == 0x78 && // X
- header[8] == 0x69 && // I
- header[9] == 0x66 && // F
- header[10] == 0x00;
-
- return isExif;
- }
-
- ///
- /// Returns a value indicating whether the given bytes identify Jpeg data.
- /// This is a last chance resort for jpegs that contain ICC information.
- ///
- /// The bytes representing the file header.
- /// The
- private static bool IsJpeg(byte[] header)
- {
- bool isJpg =
- header[0] == 0xFF && // 255
- header[1] == 0xD8; // 216
-
- return isJpg;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Jpg/JpegDecoderCore.cs.REMOVED.git-id b/src/ImageProcessorCore - Copy/Formats/Jpg/JpegDecoderCore.cs.REMOVED.git-id
deleted file mode 100644
index a5c139745c..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Jpg/JpegDecoderCore.cs.REMOVED.git-id
+++ /dev/null
@@ -1 +0,0 @@
-7a5076971068e0f389da2fb1e8b25216f4049718
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/Formats/Jpg/JpegEncoder.cs b/src/ImageProcessorCore - Copy/Formats/Jpg/JpegEncoder.cs
deleted file mode 100644
index 32c4d5f288..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Jpg/JpegEncoder.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
-
- ///
- /// Encoder for writing the data image to a stream in jpeg format.
- ///
- public class JpegEncoder : IImageEncoder
- {
- ///
- /// The quality used to encode the image.
- ///
- private int quality = 75;
-
- ///
- /// The subsamples scheme used to encode the image.
- ///
- private JpegSubsample subsample = JpegSubsample.Ratio420;
-
- ///
- /// Whether subsampling has been specifically set.
- ///
- private bool subsampleSet;
-
- ///
- /// Gets or sets the quality, that will be used to encode the image. Quality
- /// index must be between 0 and 100 (compression from max to min).
- ///
- ///
- /// If the quality is less than or equal to 80, the subsampling ratio will switch to
- ///
- /// The quality of the jpg image from 0 to 100.
- public int Quality
- {
- get { return this.quality; }
- set { this.quality = value.Clamp(1, 100); }
- }
-
- ///
- /// Gets or sets the subsample ration, that will be used to encode the image.
- ///
- /// The subsample ratio of the jpg image.
- public JpegSubsample Subsample
- {
- get { return this.subsample; }
- set
- {
- this.subsample = value;
- this.subsampleSet = true;
- }
- }
-
- ///
- public string MimeType => "image/jpeg";
-
- ///
- public string Extension => "jpg";
-
- ///
- public bool IsSupportedFileExtension(string extension)
- {
- Guard.NotNullOrEmpty(extension, "extension");
-
- if (extension.StartsWith("."))
- {
- extension = extension.Substring(1);
- }
-
- return extension.Equals(this.Extension, StringComparison.OrdinalIgnoreCase) ||
- extension.Equals("jpeg", StringComparison.OrdinalIgnoreCase) ||
- extension.Equals("jfif", StringComparison.OrdinalIgnoreCase);
- }
-
- ///
- public void Encode(ImageBase image, Stream stream)
- {
- Guard.NotNull(image, nameof(image));
- Guard.NotNull(stream, nameof(stream));
-
- JpegEncoderCore encode = new JpegEncoderCore();
- if (this.subsampleSet)
- {
- encode.Encode(stream, image, this.Quality, this.Subsample);
- }
- else
- {
- encode.Encode(stream, image, this.Quality, this.Quality >= 80 ? JpegSubsample.Ratio444 : JpegSubsample.Ratio420);
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Jpg/JpegEncoderCore.cs b/src/ImageProcessorCore - Copy/Formats/Jpg/JpegEncoderCore.cs
deleted file mode 100644
index 384f18b36a..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Jpg/JpegEncoderCore.cs
+++ /dev/null
@@ -1,783 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
-
- internal class JpegEncoderCore
- {
- ///
- /// Maps from the zig-zag ordering to the natural ordering. For example,
- /// unzig[3] is the column and row of the fourth element in zig-zag order. The
- /// value is 16, which means first column (16%8 == 0) and third row (16/8 == 2).
- ///
- private static readonly int[] Unzig =
- {
- 0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5, 12, 19, 26,
- 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28, 35, 42, 49, 56, 57,
- 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51, 58, 59, 52, 45, 38, 31,
- 39, 46, 53, 60, 61, 54, 47, 55, 62, 63,
- };
-
- private const int NQuantIndex = 2;
-
- ///
- /// Counts the number of bits needed to hold an integer.
- ///
- private readonly byte[] bitCount =
- {
- 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5,
- 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
- 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
- 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
- 8, 8, 8, 8, 8, 8,
- };
-
- ///
- /// The unscaled quantization tables in zig-zag order. Each
- /// encoder copies and scales the tables according to its quality parameter.
- /// The values are derived from section K.1 after converting from natural to
- /// zig-zag order.
- ///
- private readonly byte[,] unscaledQuant = {
- {
- // Luminance.
- 16, 11, 12, 14, 12, 10, 16, 14, 13, 14, 18, 17, 16, 19, 24, 40,
- 26, 24, 22, 22, 24, 49, 35, 37, 29, 40, 58, 51, 61, 60, 57, 51,
- 56, 55, 64, 72, 92, 78, 64, 68, 87, 69, 55, 56, 80, 109, 81,
- 87, 95, 98, 103, 104, 103, 62, 77, 113, 121, 112, 100, 120, 92,
- 101, 103, 99,
- },
- {
- // Chrominance.
- 17, 18, 18, 24, 21, 24, 47, 26, 26, 47, 99, 66, 56, 66, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99, 99,
- }
- };
-
- ///
- /// The Huffman encoding specifications.
- /// This encoder uses the same Huffman encoding for all images.
- ///
- private readonly HuffmanSpec[] theHuffmanSpec = {
- // Luminance DC.
- new HuffmanSpec(
- new byte[]
- {
- 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
- },
- new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }),
- new HuffmanSpec(
- new byte[]
- {
- 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125
- },
- new byte[]
- {
- 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21,
- 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71,
- 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1,
- 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72,
- 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25,
- 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37,
- 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
- 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
- 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,
- 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83,
- 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93,
- 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3,
- 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3,
- 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
- 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3,
- 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
- 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1,
- 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa
- }),
- new HuffmanSpec(
- new byte[]
- {
- 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
- },
- new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 }),
-
- // Chrominance AC.
- new HuffmanSpec(
- new byte[]
- {
- 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119
- },
- new byte[]
- {
- 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31,
- 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22,
- 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1,
- 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1,
- 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18,
- 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36,
- 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47,
- 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
- 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
- 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a,
- 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,
- 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
- 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
- 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,
- 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
- 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
- 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa,
- })
- };
-
- ///
- /// A compiled look-up table representation of a huffmanSpec.
- /// Each value maps to a uint32 of which the 8 most significant bits hold the
- /// codeword size in bits and the 24 least significant bits hold the codeword.
- /// The maximum codeword size is 16 bits.
- ///
- private class HuffmanLut
- {
- public readonly uint[] Values;
-
- public HuffmanLut(HuffmanSpec s)
- {
- int maxValue = 0;
-
- foreach (var v in s.Values)
- {
- if (v > maxValue) maxValue = v;
- }
-
- this.Values = new uint[maxValue + 1];
-
- int code = 0;
- int k = 0;
-
- for (int i = 0; i < s.Count.Length; i++)
- {
- int nBits = (i + 1) << 24;
- for (int j = 0; j < s.Count[i]; j++)
- {
- this.Values[s.Values[k]] = (uint)(nBits | code);
- code++;
- k++;
- }
-
- code <<= 1;
- }
- }
- }
-
- // w is the writer to write to. err is the first error encountered during
- // writing. All attempted writes after the first error become no-ops.
- private Stream outputStream;
-
- ///
- /// A scratch buffer to reduce allocations.
- ///
- private readonly byte[] buffer = new byte[16];
-
- ///
- /// The accumulated bits to write to the stream.
- ///
- private uint bits;
-
- ///
- /// The accumulated bits to write to the stream.
- ///
- private uint nBits;
-
- ///
- /// The scaled quantization tables, in zig-zag order.
- ///
- private readonly byte[][] quant = new byte[NQuantIndex][]; // [Block.blockSize];
-
- // The compiled representations of theHuffmanSpec.
- private readonly HuffmanLut[] theHuffmanLUT = new HuffmanLut[4];
-
- ///
- /// The subsampling method to use.
- ///
- private JpegSubsample subsample;
-
- ///
- /// Writes the given byte to the stream.
- ///
- ///
- private void WriteByte(byte b)
- {
- var data = new byte[1];
- data[0] = b;
- this.outputStream.Write(data, 0, 1);
- }
-
- ///
- /// Emits the least significant nBits bits of bits to the bit-stream.
- /// The precondition is bits < 1<<nBits && nBits <= 16.
- ///
- ///
- ///
- private void Emit(uint bits, uint nBits)
- {
- nBits += this.nBits;
- bits <<= (int)(32 - nBits);
- bits |= this.bits;
- while (nBits >= 8)
- {
- byte b = (byte)(bits >> 24);
- this.WriteByte(b);
- if (b == 0xff) this.WriteByte(0x00);
- bits <<= 8;
- nBits -= 8;
- }
-
- this.bits = bits;
- this.nBits = nBits;
- }
-
- ///
- /// Emits the given value with the given Huffman encoder.
- ///
- /// The index of the Huffman encoder
- /// The value to encode.
- private void EmitHuff(HuffIndex index, int value)
- {
- uint x = this.theHuffmanLUT[(int)index].Values[value];
- this.Emit(x & ((1 << 24) - 1), x >> 24);
- }
-
- ///
- /// Emits a run of runLength copies of value encoded with the given Huffman encoder.
- ///
- /// The index of the Huffman encoder
- /// The number of copies to encode.
- /// The value to encode.
- private void EmitHuffRLE(HuffIndex index, int runLength, int value)
- {
- int a = value;
- int b = value;
- if (a < 0)
- {
- a = -value;
- b = value - 1;
- }
-
- uint bt;
- if (a < 0x100)
- {
- bt = this.bitCount[a];
- }
- else
- {
- bt = 8 + (uint)this.bitCount[a >> 8];
- }
-
- this.EmitHuff(index, (int)((uint)(runLength << 4) | bt));
- if (bt > 0)
- {
- this.Emit((uint)b & (uint)((1 << ((int)bt)) - 1), bt);
- }
- }
-
-
- ///
- /// Writes a block of pixel data using the given quantization table,
- /// returning the post-quantized DC value of the DCT-transformed block.
- /// The block is in natural (not zig-zag) order.
- ///
- /// The block to write.
- /// The quantization table index.
- /// The previous DC value.
- ///
- private int WriteBlock(Block block, QuantIndex index, int prevDC)
- {
- FDCT.Transform(block);
-
- // Emit the DC delta.
- int dc = Round(block[0], 8 * this.quant[(int)index][0]);
- this.EmitHuffRLE((HuffIndex)(2 * (int)index + 0), 0, dc - prevDC);
-
- // Emit the AC components.
- var h = (HuffIndex)(2 * (int)index + 1);
- int runLength = 0;
-
- for (int zig = 1; zig < Block.BlockSize; zig++)
- {
- int ac = Round(block[Unzig[zig]], 8 * this.quant[(int)index][zig]);
-
- if (ac == 0)
- {
- runLength++;
- }
- else
- {
- while (runLength > 15)
- {
- this.EmitHuff(h, 0xf0);
- runLength -= 16;
- }
-
- this.EmitHuffRLE(h, runLength, ac);
- runLength = 0;
- }
- }
-
- if (runLength > 0) this.EmitHuff(h, 0x00);
- return dc;
- }
-
- // toYCbCr converts the 8x8 region of m whose top-left corner is p to its
- // YCbCr values.
- private void ToYCbCr(PixelAccessor pixels, int x, int y, Block yBlock, Block cbBlock, Block crBlock)
- {
- int xmax = pixels.Width - 1;
- int ymax = pixels.Height - 1;
- for (int j = 0; j < 8; j++)
- {
- for (int i = 0; i < 8; i++)
- {
- YCbCr color = pixels[Math.Min(x + i, xmax), Math.Min(y + j, ymax)];
- int index = (8 * j) + i;
- yBlock[index] = (int)color.Y;
- cbBlock[index] = (int)color.Cb;
- crBlock[index] = (int)color.Cr;
- }
- }
- }
-
- ///
- /// Scales the 16x16 region represented by the 4 src blocks to the 8x8
- /// dst block.
- ///
- /// The destination block array
- /// The source block array.
- private void Scale16X16_8X8(Block destination, Block[] source)
- {
- for (int i = 0; i < 4; i++)
- {
- int dstOff = ((i & 2) << 4) | ((i & 1) << 2);
- for (int y = 0; y < 4; y++)
- {
- for (int x = 0; x < 4; x++)
- {
- int j = 16 * y + 2 * x;
- int sum = source[i][j] + source[i][j + 1] + source[i][j + 8] + source[i][j + 9];
- destination[8 * y + x + dstOff] = (sum + 2) / 4;
- }
- }
- }
- }
-
- // The SOS marker "\xff\xda" followed by 8 bytes:
- // - the marker length "\x00\x08",
- // - the number of components "\x01",
- // - component 1 uses DC table 0 and AC table 0 "\x01\x00",
- // - the bytes "\x00\x3f\x00". Section B.2.3 of the spec says that for
- // sequential DCTs, those bytes (8-bit Ss, 8-bit Se, 4-bit Ah, 4-bit Al)
- // should be 0x00, 0x3f, 0x00<<4 | 0x00.
- private readonly byte[] SOSHeaderY =
- {
- JpegConstants.Markers.XFF, JpegConstants.Markers.SOS,
- 0x00, 0x08, // Length (high byte, low byte), must be 6 + 2 * (number of components in scan)
- 0x01, // Number of components in a scan, 1
- 0x01, // Component Id Y
- 0x00, // DC/AC Huffman table
- 0x00, // Ss - Start of spectral selection.
- 0x3f, // Se - End of spectral selection.
- 0x00 // Ah + Ah (Successive approximation bit position high + low)
- };
-
- // The SOS marker "\xff\xda" followed by 12 bytes:
- // - the marker length "\x00\x0c",
- // - the number of components "\x03",
- // - component 1 uses DC table 0 and AC table 0 "\x01\x00",
- // - component 2 uses DC table 1 and AC table 1 "\x02\x11",
- // - component 3 uses DC table 1 and AC table 1 "\x03\x11",
- // - the bytes "\x00\x3f\x00". Section B.2.3 of the spec says that for
- // sequential DCTs, those bytes (8-bit Ss, 8-bit Se, 4-bit Ah, 4-bit Al)
- // should be 0x00, 0x3f, 0x00<<4 | 0x00.
- private readonly byte[] SOSHeaderYCbCr =
- {
- JpegConstants.Markers.XFF, JpegConstants.Markers.SOS,
- 0x00, 0x0c, // Length (high byte, low byte), must be 6 + 2 * (number of components in scan)
- 0x03, // Number of components in a scan, 3
- 0x01, // Component Id Y
- 0x00, // DC/AC Huffman table
- 0x02, // Component Id Cb
- 0x11, // DC/AC Huffman table
- 0x03, // Component Id Cr
- 0x11, // DC/AC Huffman table
- 0x00, // Ss - Start of spectral selection.
- 0x3f, // Se - End of spectral selection.
- 0x00 // Ah + Ah (Successive approximation bit position high + low)
- };
-
- // Encode writes the Image m to w in JPEG 4:2:0 baseline format with the given
- // options. Default parameters are used if a nil *Options is passed.
- public void Encode(Stream stream, ImageBase image, int quality, JpegSubsample sample)
- {
- Guard.NotNull(image, nameof(image));
- Guard.NotNull(stream, nameof(stream));
-
- ushort max = JpegConstants.MaxLength;
- if (image.Width >= max || image.Height >= max)
- {
- throw new ImageFormatException($"Image is too large to encode at {image.Width}x{image.Height}.");
- }
-
- this.outputStream = stream;
- this.subsample = sample;
-
- // TODO: This should be static should it not?
- for (int i = 0; i < this.theHuffmanSpec.Length; i++)
- {
- this.theHuffmanLUT[i] = new HuffmanLut(this.theHuffmanSpec[i]);
- }
-
- for (int i = 0; i < NQuantIndex; i++)
- {
- this.quant[i] = new byte[Block.BlockSize];
- }
-
- if (quality < 1) quality = 1;
- if (quality > 100) quality = 100;
-
- // Convert from a quality rating to a scaling factor.
- int scale;
- if (quality < 50)
- {
- scale = 5000 / quality;
- }
- else
- {
- scale = 200 - quality * 2;
- }
-
- // Initialize the quantization tables.
- for (int i = 0; i < NQuantIndex; i++)
- {
- for (int j = 0; j < Block.BlockSize; j++)
- {
- int x = this.unscaledQuant[i, j];
- x = (x * scale + 50) / 100;
- if (x < 1) x = 1;
- if (x > 255) x = 255;
- this.quant[i][j] = (byte)x;
- }
- }
-
- // Compute number of components based on input image type.
- int componentCount = 3;
-
- // Write the Start Of Image marker.
- // TODO: JFIF header etc.
- this.buffer[0] = 0xff;
- this.buffer[1] = 0xd8;
- stream.Write(this.buffer, 0, 2);
-
- // Write the quantization tables.
- this.WriteDQT();
-
- // Write the image dimensions.
- this.WriteSOF0(image.Width, image.Height, componentCount);
-
- // Write the Huffman tables.
- this.WriteDHT(componentCount);
-
- // Write the image data.
- using (PixelAccessor pixels = image.Lock())
- {
- this.WriteSOS(pixels);
- }
-
- // Write the End Of Image marker.
- this.buffer[0] = 0xff;
- this.buffer[1] = 0xd9;
- stream.Write(this.buffer, 0, 2);
- stream.Flush();
- }
-
- ///
- /// Gets the quotient of the two numbers rounded to the nearest integer, instead of rounded to zero.
- ///
- /// The value to divide.
- /// The value to divide by.
- /// The
- private static int Round(int dividend, int divisor)
- {
- if (dividend >= 0)
- {
- return (dividend + (divisor >> 1)) / divisor;
- }
-
- return -((-dividend + (divisor >> 1)) / divisor);
- }
-
- ///
- /// Writes the Define Quantization Marker and tables.
- ///
- private void WriteDQT()
- {
- int markerlen = 2 + NQuantIndex * (1 + Block.BlockSize);
- this.WriteMarkerHeader(JpegConstants.Markers.DQT, markerlen);
- for (int i = 0; i < NQuantIndex; i++)
- {
- this.WriteByte((byte)i);
- this.outputStream.Write(this.quant[i], 0, this.quant[i].Length);
- }
- }
-
- ///
- /// Writes the Start Of Frame (Baseline) marker
- ///
- /// The width of the image
- /// The height of the image
- ///
- private void WriteSOF0(int width, int height, int componentCount)
- {
- // "default" to 4:2:0
- byte[] subsamples = { 0x22, 0x11, 0x11 };
- byte[] chroma = { 0x00, 0x01, 0x01 };
-
- switch (this.subsample)
- {
- case JpegSubsample.Ratio444:
- subsamples = new byte[] { 0x11, 0x11, 0x11 };
- break;
- case JpegSubsample.Ratio420:
- subsamples = new byte[] { 0x22, 0x11, 0x11 };
- break;
- }
-
- // Length (high byte, low byte), 8 + components * 3.
- int markerlen = 8 + 3 * componentCount;
- this.WriteMarkerHeader(JpegConstants.Markers.SOF0, markerlen);
- this.buffer[0] = 8; // Data Precision. 8 for now, 12 and 16 bit jpegs not supported
- this.buffer[1] = (byte)(height >> 8);
- this.buffer[2] = (byte)(height & 0xff); // (2 bytes, Hi-Lo), must be > 0 if DNL not supported
- this.buffer[3] = (byte)(width >> 8);
- this.buffer[4] = (byte)(width & 0xff); // (2 bytes, Hi-Lo), must be > 0 if DNL not supported
- this.buffer[5] = (byte)componentCount; // Number of components (1 byte), usually 1 = grey scaled, 3 = color YCbCr or YIQ, 4 = color CMYK)
- if (componentCount == 1)
- {
- this.buffer[6] = 1;
-
- // No subsampling for grayscale images.
- this.buffer[7] = 0x11;
- this.buffer[8] = 0x00;
- }
- else
- {
- for (int i = 0; i < componentCount; i++)
- {
- this.buffer[3 * i + 6] = (byte)(i + 1);
-
- // We use 4:2:0 chroma subsampling by default.
- this.buffer[3 * i + 7] = subsamples[i];
- this.buffer[3 * i + 8] = chroma[i];
- }
- }
-
- this.outputStream.Write(this.buffer, 0, 3 * (componentCount - 1) + 9);
- }
-
- ///
- /// Writes the Define Huffman Table marker and tables.
- ///
- /// The number of components to write.
- private void WriteDHT(int nComponent)
- {
- byte[] headers = { 0x00, 0x10, 0x01, 0x11 };
- int markerlen = 2;
- HuffmanSpec[] specs = this.theHuffmanSpec;
-
- if (nComponent == 1)
- {
- // Drop the Chrominance tables.
- specs = new[] { this.theHuffmanSpec[0], this.theHuffmanSpec[1] };
- }
-
- foreach (var s in specs)
- {
- markerlen += 1 + 16 + s.Values.Length;
- }
-
- this.WriteMarkerHeader(JpegConstants.Markers.DHT, markerlen);
- for (int i = 0; i < specs.Length; i++)
- {
- HuffmanSpec spec = specs[i];
-
- this.WriteByte(headers[i]);
- this.outputStream.Write(spec.Count, 0, spec.Count.Length);
- this.outputStream.Write(spec.Values, 0, spec.Values.Length);
- }
- }
-
- ///
- /// Writes the StartOfScan marker.
- ///
- /// The pixel accessor providing acces to the image pixels.
- private void WriteSOS(PixelAccessor pixels)
- {
- // TODO: We should allow grayscale writing.
- this.outputStream.Write(this.SOSHeaderYCbCr, 0, this.SOSHeaderYCbCr.Length);
-
- switch (this.subsample)
- {
- case JpegSubsample.Ratio444:
- this.Encode444(pixels);
- break;
- case JpegSubsample.Ratio420:
- this.Encode420(pixels);
- break;
- }
-
- // Pad the last byte with 1's.
- this.Emit(0x7f, 7);
- }
-
-
-
- ///
- /// Encodes the image with no subsampling.
- ///
- /// The pixel accessor providing acces to the image pixels.
- private void Encode444(PixelAccessor pixels)
- {
- Block b = new Block();
- Block cb = new Block();
- Block cr = new Block();
- int prevDCY = 0, prevDCCb = 0, prevDCCr = 0;
-
- for (int y = 0; y < pixels.Height; y += 8)
- {
- for (int x = 0; x < pixels.Width; x += 8)
- {
- this.ToYCbCr(pixels, x, y, b, cb, cr);
- prevDCY = this.WriteBlock(b, QuantIndex.Luminance, prevDCY);
- prevDCCb = this.WriteBlock(cb, QuantIndex.Chrominance, prevDCCb);
- prevDCCr = this.WriteBlock(cr, QuantIndex.Chrominance, prevDCCr);
- }
- }
- }
-
- ///
- /// Encodes the image with subsampling. The Cb and Cr components are each subsampled
- /// at a factor of 2 both horizontally and vertically.
- ///
- /// The pixel accessor providing acces to the image pixels.
- private void Encode420(PixelAccessor pixels)
- {
- Block b = new Block();
- Block[] cb = new Block[4];
- Block[] cr = new Block[4];
- int prevDCY = 0, prevDCCb = 0, prevDCCr = 0;
-
- for (int i = 0; i < 4; i++) cb[i] = new Block();
- for (int i = 0; i < 4; i++) cr[i] = new Block();
-
- for (int y = 0; y < pixels.Height; y += 16)
- {
- for (int x = 0; x < pixels.Width; x += 16)
- {
- for (int i = 0; i < 4; i++)
- {
- int xOff = (i & 1) * 8;
- int yOff = (i & 2) * 4;
-
- this.ToYCbCr(pixels, x + xOff, y + yOff, b, cb[i], cr[i]);
- prevDCY = this.WriteBlock(b, QuantIndex.Luminance, prevDCY);
- }
-
- this.Scale16X16_8X8(b, cb);
- prevDCCb = this.WriteBlock(b, QuantIndex.Chrominance, prevDCCb);
- this.Scale16X16_8X8(b, cr);
- prevDCCr = this.WriteBlock(b, QuantIndex.Chrominance, prevDCCr);
- }
- }
- }
-
- ///
- /// Writes the header for a marker with the given length.
- ///
- /// The marker to write.
- /// The marker length.
- private void WriteMarkerHeader(byte marker, int length)
- {
- // Markers are always prefixed with with 0xff.
- this.buffer[0] = JpegConstants.Markers.XFF;
- this.buffer[1] = marker;
- this.buffer[2] = (byte)(length >> 8);
- this.buffer[3] = (byte)(length & 0xff);
- this.outputStream.Write(this.buffer, 0, 4);
- }
-
- ///
- /// Enumerates the Huffman tables
- ///
- private enum HuffIndex
- {
- LuminanceDC = 0,
-
- LuminanceAC = 1,
-
- ChrominanceDC = 2,
-
- ChrominanceAC = 3,
- }
-
- ///
- /// Enumerates the quantization tables
- ///
- private enum QuantIndex
- {
- ///
- /// Luminance
- ///
- Luminance = 0,
-
- ///
- /// Chrominance
- ///
- Chrominance = 1,
- }
-
- ///
- /// The Huffman encoding specifications.
- ///
- private struct HuffmanSpec
- {
- ///
- /// Initializes a n ew instance of the struct.
- ///
- /// The number of codes.
- /// The decoded values.
- public HuffmanSpec(byte[] count, byte[] values)
- {
- this.Count = count;
- this.Values = values;
- }
-
- ///
- /// Gets count[i] - The number of codes of length i bits.
- ///
- public readonly byte[] Count;
-
- ///
- /// Gets value[i] - The decoded value of the i'th codeword.
- ///
- public readonly byte[] Values;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Jpg/JpegFormat.cs b/src/ImageProcessorCore - Copy/Formats/Jpg/JpegFormat.cs
deleted file mode 100644
index ec9ceb6dc0..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Jpg/JpegFormat.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Encapsulates the means to encode and decode jpeg images.
- ///
- public class JpegFormat : IImageFormat
- {
- ///
- public IImageDecoder Decoder => new JpegDecoder();
-
- ///
- public IImageEncoder Encoder => new JpegEncoder();
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Jpg/JpegSubsample.cs b/src/ImageProcessorCore - Copy/Formats/Jpg/JpegSubsample.cs
deleted file mode 100644
index 6098f6377b..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Jpg/JpegSubsample.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Enumerates the chroma subsampling method applied to the image.
- ///
- public enum JpegSubsample
- {
- ///
- /// High Quality - Each of the three Y'CbCr components have the same sample rate,
- /// thus there is no chroma subsampling.
- ///
- Ratio444,
-
- ///
- /// Medium Quality - The horizontal sampling is halved and the Cb and Cr channels are only
- /// sampled on each alternate line.
- ///
- Ratio420
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Jpg/README.md b/src/ImageProcessorCore - Copy/Formats/Jpg/README.md
deleted file mode 100644
index 54bc14847c..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Jpg/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-Encoder/Decoder adapted and extended from:
-
-https://golang.org/src/image/jpeg/
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/GrayscaleReader.cs b/src/ImageProcessorCore - Copy/Formats/Png/GrayscaleReader.cs
deleted file mode 100644
index 87f074e0bd..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/GrayscaleReader.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Color reader for reading grayscale colors from a png file.
- ///
- internal sealed class GrayscaleReader : IColorReader
- {
- ///
- /// Whether t also read the alpha channel.
- ///
- private readonly bool useAlpha;
-
- ///
- /// The current row.
- ///
- private int row;
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// If set to true the color reader will also read the
- /// alpha channel from the scanline.
- ///
- public GrayscaleReader(bool useAlpha)
- {
- this.useAlpha = useAlpha;
- }
-
- ///
- public void ReadScanline(byte[] scanline, float[] pixels, PngHeader header)
- {
- int offset;
-
- byte[] newScanline = scanline.ToArrayByBitsLength(header.BitDepth);
-
- // We divide by 255 as we will store the colors in our floating point format.
- // Stored in r-> g-> b-> a order.
- if (this.useAlpha)
- {
- for (int x = 0; x < header.Width / 2; x++)
- {
- offset = ((this.row * header.Width) + x) * 4;
-
- // We want to convert to premultiplied alpha here.
- float r = newScanline[x * 2] / 255f;
- float g = newScanline[x * 2] / 255f;
- float b = newScanline[x * 2] / 255f;
- float a = newScanline[(x * 2) + 1] / 255f;
-
- Color premultiplied = Color.FromNonPremultiplied(new Color(r, g, b, a));
-
- pixels[offset] = premultiplied.R;
- pixels[offset + 1] = premultiplied.G;
- pixels[offset + 2] = premultiplied.B;
- pixels[offset + 3] = premultiplied.A;
- }
- }
- else
- {
- for (int x = 0; x < header.Width; x++)
- {
- offset = ((this.row * header.Width) + x) * 4;
-
- pixels[offset] = newScanline[x] / 255f;
- pixels[offset + 1] = newScanline[x] / 255f;
- pixels[offset + 2] = newScanline[x] / 255f;
- pixels[offset + 3] = 1;
- }
- }
-
- this.row++;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/IColorReader.cs b/src/ImageProcessorCore - Copy/Formats/Png/IColorReader.cs
deleted file mode 100644
index 68183fac72..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/IColorReader.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Encapsulates methods for color readers, which are responsible for reading
- /// different color formats from a png file.
- ///
- public interface IColorReader
- {
- ///
- /// Reads the specified scanline.
- ///
- /// The scanline.
- /// The pixels, where the colors should be stored in RGBA format.
- ///
- /// The header, which contains information about the png file, like
- /// the width of the image and the height.
- ///
- void ReadScanline(byte[] scanline, float[] pixels, PngHeader header);
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/PaletteIndexReader.cs b/src/ImageProcessorCore - Copy/Formats/Png/PaletteIndexReader.cs
deleted file mode 100644
index 40de59dbb8..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/PaletteIndexReader.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// A color reader for reading palette indices from the png file.
- ///
- internal sealed class PaletteIndexReader : IColorReader
- {
- ///
- /// The palette.
- ///
- private readonly byte[] palette;
-
- ///
- /// The alpha palette.
- ///
- private readonly byte[] paletteAlpha;
-
- ///
- /// The current row.
- ///
- private int row;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The palette as simple byte array. It will contains 3 values for each
- /// color, which represents the red-, the green- and the blue channel.
- /// The alpha palette. Can be null, if the image does not have an
- /// alpha channel and can contain less entries than the number of colors in the palette.
- public PaletteIndexReader(byte[] palette, byte[] paletteAlpha)
- {
- this.palette = palette;
- this.paletteAlpha = paletteAlpha;
- }
-
- ///
- public void ReadScanline(byte[] scanline, float[] pixels, PngHeader header)
- {
- byte[] newScanline = scanline.ToArrayByBitsLength(header.BitDepth);
- int offset, index;
-
- if (this.paletteAlpha != null && this.paletteAlpha.Length > 0)
- {
- // If the alpha palette is not null and does one or
- // more entries, this means, that the image contains and alpha
- // channel and we should try to read it.
- for (int i = 0; i < header.Width; i++)
- {
- index = newScanline[i];
-
- offset = ((this.row * header.Width) + i) * 4;
- int pixelOffset = index * 3;
-
- // BUGFIX changed newScanline[] to this.palette[] , 99% sure it was a typo and not intent
- float r = this.palette[pixelOffset] / 255f;
- float g = this.palette[pixelOffset + 1] / 255f;
- float b = this.palette[pixelOffset + 2] / 255f;
- float a = this.paletteAlpha.Length > index
- ? this.paletteAlpha[index] / 255f
- : 1;
-
- Color color = new Color(r, g, b, a);
- if (color.A < 1)
- {
- // We want to convert to premultiplied alpha here.
- color = Color.FromNonPremultiplied(color);
- }
-
- pixels[offset] = color.R;
- pixels[offset + 1] = color.G;
- pixels[offset + 2] = color.B;
- pixels[offset + 3] = color.A;
- }
- }
- else
- {
- for (int i = 0; i < header.Width; i++)
- {
- index = newScanline[i];
-
- offset = ((this.row * header.Width) + i) * 4;
- int pixelOffset = index * 3;
-
- pixels[offset] = this.palette[pixelOffset] / 255f;
- pixels[offset + 1] = this.palette[pixelOffset + 1] / 255f;
- pixels[offset + 2] = this.palette[pixelOffset + 2] / 255f;
- pixels[offset + 3] = 1;
- }
- }
-
- this.row++;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/PngChunk.cs b/src/ImageProcessorCore - Copy/Formats/Png/PngChunk.cs
deleted file mode 100644
index 31ea703a65..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/PngChunk.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Stores header information about a chunk.
- ///
- internal sealed class PngChunk
- {
- ///
- /// Gets or sets the length.
- /// An unsigned integer giving the number of bytes in the chunk's
- /// data field. The length counts only the data field, not itself,
- /// the chunk type code, or the CRC. Zero is a valid length
- ///
- public int Length { get; set; }
-
- ///
- /// Gets or sets the chunk type as string with 4 chars.
- ///
- public string Type { get; set; }
-
- ///
- /// Gets or sets the data bytes appropriate to the chunk type, if any.
- /// This field can be of zero length.
- ///
- public byte[] Data { get; set; }
-
- ///
- /// Gets or sets a CRC (Cyclic Redundancy Check) calculated on the preceding bytes in the chunk,
- /// including the chunk type code and chunk data fields, but not including the length field.
- /// The CRC is always present, even for chunks containing no data
- ///
- public uint Crc { get; set; }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/PngChunkTypes.cs b/src/ImageProcessorCore - Copy/Formats/Png/PngChunkTypes.cs
deleted file mode 100644
index 5c35b3d4d2..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/PngChunkTypes.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Contains a list of possible chunk type identifiers.
- ///
- internal static class PngChunkTypes
- {
- ///
- /// The first chunk in a png file. Can only exists once. Contains
- /// common information like the width and the height of the image or
- /// the used compression method.
- ///
- public const string Header = "IHDR";
-
- ///
- /// The PLTE chunk contains from 1 to 256 palette entries, each a three byte
- /// series in the RGB format.
- ///
- public const string Palette = "PLTE";
-
- ///
- /// The IDAT chunk contains the actual image data. The image can contains more
- /// than one chunk of this type. All chunks together are the whole image.
- ///
- public const string Data = "IDAT";
-
- ///
- /// This chunk must appear last. It marks the end of the PNG data stream.
- /// The chunk's data field is empty.
- ///
- public const string End = "IEND";
-
- ///
- /// This chunk specifies that the image uses simple transparency:
- /// either alpha values associated with palette entries (for indexed-color images)
- /// or a single transparent color (for grayscale and true color images).
- ///
- public const string PaletteAlpha = "tRNS";
-
- ///
- /// Textual information that the encoder wishes to record with the image can be stored in
- /// tEXt chunks. Each tEXt chunk contains a keyword and a text string.
- ///
- public const string Text = "tEXt";
-
- ///
- /// This chunk specifies the relationship between the image samples and the desired
- /// display output intensity.
- ///
- public const string Gamma = "gAMA";
-
- ///
- /// The pHYs chunk specifies the intended pixel size or aspect ratio for display of the image.
- ///
- public const string Physical = "pHYs";
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/PngColorTypeInformation.cs b/src/ImageProcessorCore - Copy/Formats/Png/PngColorTypeInformation.cs
deleted file mode 100644
index 9909cf47cc..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/PngColorTypeInformation.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
-
- ///
- /// Contains information that are required when loading a png with a specific color type.
- ///
- internal sealed class PngColorTypeInformation
- {
- ///
- /// Initializes a new instance of the class with
- /// the scanline factory, the function to create the color reader and the supported bit depths.
- ///
- /// The scanline factor.
- /// The supported bit depths.
- /// The factory to create the color reader.
- public PngColorTypeInformation(int scanlineFactor, int[] supportedBitDepths, Func scanlineReaderFactory)
- {
- this.ChannelsPerColor = scanlineFactor;
- this.ScanlineReaderFactory = scanlineReaderFactory;
- this.SupportedBitDepths = supportedBitDepths;
- }
-
- ///
- /// Gets an array with the bit depths that are supported for the color type
- /// where this object is created for.
- ///
- /// The supported bit depths that can be used in combination with this color type.
- public int[] SupportedBitDepths { get; private set; }
-
- ///
- /// Gets a function that is used the create the color reader for the color type where
- /// this object is created for.
- ///
- /// The factory function to create the color type.
- public Func ScanlineReaderFactory { get; private set; }
-
- ///
- /// Gets a factor that is used when iterating through the scan lines.
- ///
- /// The scanline factor.
- public int ChannelsPerColor { get; private set; }
-
- ///
- /// Creates the color reader for the color type where this object is create for.
- ///
- /// The palette of the image. Can be null when no palette is used.
- /// The alpha palette of the image. Can be null when
- /// no palette is used for the image or when the image has no alpha.
- /// The color reader for the image.
- public IColorReader CreateColorReader(byte[] palette, byte[] paletteAlpha)
- {
- return this.ScanlineReaderFactory(palette, paletteAlpha);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/PngDecoder.cs b/src/ImageProcessorCore - Copy/Formats/Png/PngDecoder.cs
deleted file mode 100644
index 7e92f26145..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/PngDecoder.cs
+++ /dev/null
@@ -1,87 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
-
- ///
- /// Encoder for generating an image out of a png encoded stream.
- ///
- ///
- /// At the moment the following features are supported:
- ///
- /// Filters: all filters are supported.
- ///
- ///
- /// Pixel formats:
- ///
- /// - RGBA (True color) with alpha (8 bit).
- /// - RGB (True color) without alpha (8 bit).
- /// - Greyscale with alpha (8 bit).
- /// - Greyscale without alpha (8 bit).
- /// - Palette Index with alpha (8 bit).
- /// - Palette Index without alpha (8 bit).
- ///
- ///
- ///
- public class PngDecoder : IImageDecoder
- {
- ///
- /// Gets the size of the header for this image type.
- ///
- /// The size of the header.
- public int HeaderSize => 8;
-
- ///
- /// Returns a value indicating whether the supports the specified
- /// file header.
- ///
- /// The containing the file extension.
- ///
- /// True if the decoder supports the file extension; otherwise, false.
- ///
- public bool IsSupportedFileExtension(string extension)
- {
- Guard.NotNullOrEmpty(extension, "extension");
-
- extension = extension.StartsWith(".") ? extension.Substring(1) : extension;
-
- return extension.Equals("PNG", StringComparison.OrdinalIgnoreCase);
- }
-
- ///
- /// Returns a value indicating whether the supports the specified
- /// file header.
- ///
- /// The containing the file header.
- ///
- /// True if the decoder supports the file header; otherwise, false.
- ///
- public bool IsSupportedFileFormat(byte[] header)
- {
- return header.Length >= 8 &&
- header[0] == 0x89 &&
- header[1] == 0x50 && // P
- header[2] == 0x4E && // N
- header[3] == 0x47 && // G
- header[4] == 0x0D && // CR
- header[5] == 0x0A && // LF
- header[6] == 0x1A && // EOF
- header[7] == 0x0A; // LF
- }
-
- ///
- /// Decodes the image from the specified stream to the .
- ///
- /// The to decode to.
- /// The containing image data.
- public void Decode(Image image, Stream stream)
- {
- new PngDecoderCore().Decode(image, stream);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/PngDecoderCore.cs b/src/ImageProcessorCore - Copy/Formats/Png/PngDecoderCore.cs
deleted file mode 100644
index a8e3596b05..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/PngDecoderCore.cs
+++ /dev/null
@@ -1,527 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
-
- ///
- /// Performs the png decoding operation.
- ///
- internal class PngDecoderCore
- {
- ///
- /// The dictionary of available color types.
- ///
- private static readonly Dictionary ColorTypes
- = new Dictionary();
-
- ///
- /// The image to decode.
- ///
- private Image currentImage;
-
- ///
- /// The stream to decode from.
- ///
- private Stream currentStream;
-
- ///
- /// The png header.
- ///
- private PngHeader header;
-
- ///
- /// Initializes static members of the class.
- ///
- static PngDecoderCore()
- {
- ColorTypes.Add(
- 0,
- new PngColorTypeInformation(1, new[] { 1, 2, 4, 8 }, (p, a) => new GrayscaleReader(false)));
-
- ColorTypes.Add(
- 2,
- new PngColorTypeInformation(3, new[] { 8 }, (p, a) => new TrueColorReader(false)));
-
- ColorTypes.Add(
- 3,
- new PngColorTypeInformation(1, new[] { 1, 2, 4, 8 }, (p, a) => new PaletteIndexReader(p, a)));
-
- ColorTypes.Add(
- 4,
- new PngColorTypeInformation(2, new[] { 8 }, (p, a) => new GrayscaleReader(true)));
-
- ColorTypes.Add(6,
- new PngColorTypeInformation(4, new[] { 8 }, (p, a) => new TrueColorReader(true)));
- }
-
- ///
- /// Decodes the stream to the image.
- ///
- /// The image to decode to.
- /// The stream containing image data.
- ///
- /// Thrown if the stream does not contain and end chunk.
- ///
- ///
- /// Thrown if the image is larger than the maximum allowable size.
- ///
- public void Decode(Image image, Stream stream)
- {
- this.currentImage = image;
- this.currentStream = stream;
- this.currentStream.Seek(8, SeekOrigin.Current);
-
- bool isEndChunkReached = false;
-
- byte[] palette = null;
- byte[] paletteAlpha = null;
-
- using (MemoryStream dataStream = new MemoryStream())
- {
- PngChunk currentChunk;
- while ((currentChunk = this.ReadChunk()) != null)
- {
- if (isEndChunkReached)
- {
- throw new ImageFormatException("Image does not end with end chunk.");
- }
-
- if (currentChunk.Type == PngChunkTypes.Header)
- {
- this.ReadHeaderChunk(currentChunk.Data);
- this.ValidateHeader();
- }
- else if (currentChunk.Type == PngChunkTypes.Physical)
- {
- this.ReadPhysicalChunk(currentChunk.Data);
- }
- else if (currentChunk.Type == PngChunkTypes.Data)
- {
- dataStream.Write(currentChunk.Data, 0, currentChunk.Data.Length);
- }
- else if (currentChunk.Type == PngChunkTypes.Palette)
- {
- palette = currentChunk.Data;
- }
- else if (currentChunk.Type == PngChunkTypes.PaletteAlpha)
- {
- paletteAlpha = currentChunk.Data;
- }
- else if (currentChunk.Type == PngChunkTypes.Text)
- {
- this.ReadTextChunk(currentChunk.Data);
- }
- else if (currentChunk.Type == PngChunkTypes.End)
- {
- isEndChunkReached = true;
- }
- }
-
- if (this.header.Width > ImageBase.MaxWidth || this.header.Height > ImageBase.MaxHeight)
- {
- throw new ArgumentOutOfRangeException(
- $"The input png '{this.header.Width}x{this.header.Height}' is bigger than the "
- + $"max allowed size '{ImageBase.MaxWidth}x{ImageBase.MaxHeight}'");
- }
-
- float[] pixels = new float[this.header.Width * this.header.Height * 4];
-
- PngColorTypeInformation colorTypeInformation = ColorTypes[this.header.ColorType];
-
- if (colorTypeInformation != null)
- {
- IColorReader colorReader = colorTypeInformation.CreateColorReader(palette, paletteAlpha);
-
- this.ReadScanlines(dataStream, pixels, colorReader, colorTypeInformation);
- }
-
- image.SetPixels(this.header.Width, this.header.Height, pixels);
- }
- }
-
- ///
- /// Computes a simple linear function of the three neighboring pixels (left, above, upper left), then chooses
- /// as predictor the neighboring pixel closest to the computed value.
- ///
- /// The left neighbour pixel.
- /// The above neighbour pixel.
- /// The upper left neighbour pixel.
- ///
- /// The .
- ///
- private static byte PaethPredicator(byte left, byte above, byte upperLeft)
- {
- byte predicator;
-
- int p = left + above - upperLeft;
- int pa = Math.Abs(p - left);
- int pb = Math.Abs(p - above);
- int pc = Math.Abs(p - upperLeft);
-
- if (pa <= pb && pa <= pc)
- {
- predicator = left;
- }
- else if (pb <= pc)
- {
- predicator = above;
- }
- else
- {
- predicator = upperLeft;
- }
-
- return predicator;
- }
-
- ///
- /// Reads the data chunk containing physical dimension data.
- ///
- /// The data containing physical data.
- private void ReadPhysicalChunk(byte[] data)
- {
- Array.Reverse(data, 0, 4);
- Array.Reverse(data, 4, 4);
-
- // 39.3700787 = inches in a meter.
- this.currentImage.HorizontalResolution = BitConverter.ToInt32(data, 0) / 39.3700787d;
- this.currentImage.VerticalResolution = BitConverter.ToInt32(data, 4) / 39.3700787d;
- }
-
- ///
- /// Calculates the scanline length.
- ///
- /// The color type information.
- /// The representing the length.
- private int CalculateScanlineLength(PngColorTypeInformation colorTypeInformation)
- {
- int scanlineLength = this.header.Width * this.header.BitDepth * colorTypeInformation.ChannelsPerColor;
-
- int amount = scanlineLength % 8;
- if (amount != 0)
- {
- scanlineLength += 8 - amount;
- }
-
- return scanlineLength / 8;
- }
-
- ///
- /// Calculates a scanline step.
- ///
- /// The color type information.
- /// The representing the length of each step.
- private int CalculateScanlineStep(PngColorTypeInformation colorTypeInformation)
- {
- int scanlineStep = 1;
-
- if (this.header.BitDepth >= 8)
- {
- scanlineStep = (colorTypeInformation.ChannelsPerColor * this.header.BitDepth) / 8;
- }
-
- return scanlineStep;
- }
-
- ///
- /// Reads the scanlines within the image.
- ///
- /// The containing data.
- ///
- /// The containing pixel data.
- /// The color reader.
- /// The color type information.
- private void ReadScanlines(MemoryStream dataStream, float[] pixels, IColorReader colorReader, PngColorTypeInformation colorTypeInformation)
- {
- dataStream.Position = 0;
-
- int scanlineLength = this.CalculateScanlineLength(colorTypeInformation);
- int scanlineStep = this.CalculateScanlineStep(colorTypeInformation);
-
- byte[] lastScanline = new byte[scanlineLength];
- byte[] currentScanline = new byte[scanlineLength];
- int filter = 0, column = -1;
-
- using (ZlibInflateStream compressedStream = new ZlibInflateStream(dataStream))
- {
- int readByte;
- while ((readByte = compressedStream.ReadByte()) >= 0)
- {
- if (column == -1)
- {
- filter = readByte;
-
- column++;
- }
- else
- {
- currentScanline[column] = (byte)readByte;
-
- byte a;
- byte b;
- byte c;
-
- if (column >= scanlineStep)
- {
- a = currentScanline[column - scanlineStep];
- c = lastScanline[column - scanlineStep];
- }
- else
- {
- a = 0;
- c = 0;
- }
-
- b = lastScanline[column];
-
- if (filter == 1)
- {
- currentScanline[column] = (byte)(currentScanline[column] + a);
- }
- else if (filter == 2)
- {
- currentScanline[column] = (byte)(currentScanline[column] + b);
- }
- else if (filter == 3)
- {
- currentScanline[column] = (byte)(currentScanline[column] + (byte)((a + b) / 2));
- }
- else if (filter == 4)
- {
- currentScanline[column] = (byte)(currentScanline[column] + PaethPredicator(a, b, c));
- }
-
- column++;
-
- if (column == scanlineLength)
- {
- colorReader.ReadScanline(currentScanline, pixels, this.header);
- column = -1;
-
- this.Swap(ref currentScanline, ref lastScanline);
- }
- }
- }
- }
- }
-
- ///
- /// Reads a text chunk containing image properties from the data.
- ///
- /// The containing data.
- private void ReadTextChunk(byte[] data)
- {
- int zeroIndex = 0;
-
- for (int i = 0; i < data.Length; i++)
- {
- if (data[i] == 0)
- {
- zeroIndex = i;
- break;
- }
- }
-
- string name = Encoding.Unicode.GetString(data, 0, zeroIndex);
- string value = Encoding.Unicode.GetString(data, zeroIndex + 1, data.Length - zeroIndex - 1);
-
- this.currentImage.Properties.Add(new ImageProperty(name, value));
- }
-
- ///
- /// Reads a header chunk from the data.
- ///
- /// The containing data.
- private void ReadHeaderChunk(byte[] data)
- {
- this.header = new PngHeader();
-
- Array.Reverse(data, 0, 4);
- Array.Reverse(data, 4, 4);
-
- this.header.Width = BitConverter.ToInt32(data, 0);
- this.header.Height = BitConverter.ToInt32(data, 4);
-
- this.header.BitDepth = data[8];
- this.header.ColorType = data[9];
- this.header.FilterMethod = data[11];
- this.header.InterlaceMethod = data[12];
- this.header.CompressionMethod = data[10];
- }
-
- ///
- /// Validates the png header.
- ///
- ///
- /// Thrown if the image does pass validation.
- ///
- private void ValidateHeader()
- {
- if (!ColorTypes.ContainsKey(this.header.ColorType))
- {
- throw new ImageFormatException("Color type is not supported or not valid.");
- }
-
- if (!ColorTypes[this.header.ColorType].SupportedBitDepths.Contains(this.header.BitDepth))
- {
- throw new ImageFormatException("Bit depth is not supported or not valid.");
- }
-
- if (this.header.FilterMethod != 0)
- {
- throw new ImageFormatException("The png specification only defines 0 as filter method.");
- }
-
- if (this.header.InterlaceMethod != 0)
- {
- throw new ImageFormatException("Interlacing is not supported.");
- }
- }
-
- ///
- /// Reads a chunk from the stream.
- ///
- ///
- /// The .
- ///
- private PngChunk ReadChunk()
- {
- PngChunk chunk = new PngChunk();
-
- if (this.ReadChunkLength(chunk) == 0)
- {
- return null;
- }
-
- byte[] typeBuffer = this.ReadChunkType(chunk);
-
- this.ReadChunkData(chunk);
- this.ReadChunkCrc(chunk, typeBuffer);
-
- return chunk;
- }
-
- ///
- /// Reads the cycle redundancy chunk from the data.
- ///
- /// The chunk.
- /// The type buffer.
- ///
- /// Thrown if the input stream is not valid or corrupt.
- ///
- private void ReadChunkCrc(PngChunk chunk, byte[] typeBuffer)
- {
- byte[] crcBuffer = new byte[4];
-
- int numBytes = this.currentStream.Read(crcBuffer, 0, 4);
- if (numBytes >= 1 && numBytes <= 3)
- {
- throw new ImageFormatException("Image stream is not valid!");
- }
-
- Array.Reverse(crcBuffer);
-
- chunk.Crc = BitConverter.ToUInt32(crcBuffer, 0);
-
- Crc32 crc = new Crc32();
- crc.Update(typeBuffer);
- crc.Update(chunk.Data);
-
- if (crc.Value != chunk.Crc)
- {
- throw new ImageFormatException("CRC Error. PNG Image chunk is corrupt!");
- }
- }
-
- ///
- /// Reads the chunk data from the stream.
- ///
- /// The chunk.
- private void ReadChunkData(PngChunk chunk)
- {
- chunk.Data = new byte[chunk.Length];
- this.currentStream.Read(chunk.Data, 0, chunk.Length);
- }
-
- ///
- /// Identifies the chunk type from the chunk.
- ///
- /// The chunk.
- ///
- /// The containing identifying information.
- ///
- ///
- /// Thrown if the input stream is not valid.
- ///
- private byte[] ReadChunkType(PngChunk chunk)
- {
- byte[] typeBuffer = new byte[4];
-
- int numBytes = this.currentStream.Read(typeBuffer, 0, 4);
- if (numBytes >= 1 && numBytes <= 3)
- {
- throw new ImageFormatException("Image stream is not valid!");
- }
-
- char[] chars = new char[4];
- chars[0] = (char)typeBuffer[0];
- chars[1] = (char)typeBuffer[1];
- chars[2] = (char)typeBuffer[2];
- chars[3] = (char)typeBuffer[3];
-
- chunk.Type = new string(chars);
-
- return typeBuffer;
- }
-
- ///
- /// Calculates the length of the given chunk.
- ///
- /// he chunk.
- ///
- /// The representing the chunk length.
- ///
- ///
- /// Thrown if the input stream is not valid.
- ///
- private int ReadChunkLength(PngChunk chunk)
- {
- byte[] lengthBuffer = new byte[4];
-
- int numBytes = this.currentStream.Read(lengthBuffer, 0, 4);
- if (numBytes >= 1 && numBytes <= 3)
- {
- throw new ImageFormatException("Image stream is not valid!");
- }
-
- Array.Reverse(lengthBuffer);
-
- chunk.Length = BitConverter.ToInt32(lengthBuffer, 0);
-
- return numBytes;
- }
-
- ///
- /// Swaps two references.
- ///
- /// The type of the references to swap.
- /// The first reference.
- /// The second reference.
- private void Swap(ref TRef lhs, ref TRef rhs)
- where TRef : class
- {
- TRef tmp = lhs;
-
- lhs = rhs;
- rhs = tmp;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/PngEncoder.cs b/src/ImageProcessorCore - Copy/Formats/Png/PngEncoder.cs
deleted file mode 100644
index 18deb10466..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/PngEncoder.cs
+++ /dev/null
@@ -1,85 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
-
- using ImageProcessorCore.Quantizers;
-
- ///
- /// Image encoder for writing image data to a stream in png format.
- ///
- public class PngEncoder : IImageEncoder
- {
- ///
- /// Gets or sets the quality of output for images.
- ///
- public int Quality { get; set; }
-
- ///
- public string MimeType => "image/png";
-
- ///
- public string Extension => "png";
-
- ///
- /// The compression level 1-9.
- /// Defaults to 6.
- ///
- public int CompressionLevel { get; set; } = 6;
-
- ///
- /// Gets or sets the gamma value, that will be written
- /// the the stream, when the property
- /// is set to true. The default value is 2.2F.
- ///
- /// The gamma value of the image.
- public float Gamma { get; set; } = 2.2F;
-
- ///
- /// The quantizer for reducing the color count.
- ///
- public IQuantizer Quantizer { get; set; }
-
- ///
- /// Gets or sets the transparency threshold.
- ///
- public byte Threshold { get; set; } = 128;
-
- ///
- /// Gets or sets a value indicating whether this instance should write
- /// gamma information to the stream. The default value is false.
- ///
- public bool WriteGamma { get; set; }
-
- ///
- public bool IsSupportedFileExtension(string extension)
- {
- Guard.NotNullOrEmpty(extension, nameof(extension));
-
- extension = extension.StartsWith(".") ? extension.Substring(1) : extension;
-
- return extension.Equals(this.Extension, StringComparison.OrdinalIgnoreCase);
- }
-
- ///
- public void Encode(ImageBase image, Stream stream)
- {
- PngEncoderCore encoder = new PngEncoderCore
- {
- CompressionLevel = this.CompressionLevel,
- Gamma = this.Gamma,
- Quality = this.Quality,
- Quantizer = this.Quantizer,
- WriteGamma = this.WriteGamma,
- Threshold = this.Threshold
- };
-
- encoder.Encode(image, stream);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/PngEncoderCore.cs b/src/ImageProcessorCore - Copy/Formats/Png/PngEncoderCore.cs
deleted file mode 100644
index 7e61f736ef..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/PngEncoderCore.cs
+++ /dev/null
@@ -1,470 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
- using System.Threading.Tasks;
-
- using ImageProcessorCore.Quantizers;
-
- ///
- /// Performs the png encoding operation.
- /// TODO: Perf. There's lots of array parsing going on here. This should be unmanaged.
- ///
- internal sealed class PngEncoderCore
- {
- ///
- /// The maximum block size, defaults at 64k for uncompressed blocks.
- ///
- private const int MaxBlockSize = 65535;
-
- ///
- /// The number of bits required to encode the colors in the png.
- ///
- private byte bitDepth;
-
- ///
- /// The quantized image result.
- ///
- private QuantizedImage quantized;
-
- ///
- /// Gets or sets the quality of output for images.
- ///
- public int Quality { get; set; }
-
- ///
- /// The compression level 1-9.
- /// Defaults to 6.
- ///
- public int CompressionLevel { get; set; } = 6;
-
- ///
- /// Gets or sets a value indicating whether this instance should write
- /// gamma information to the stream. The default value is false.
- ///
- public bool WriteGamma { get; set; }
-
- ///
- /// Gets or sets the gamma value, that will be written
- /// the the stream, when the property
- /// is set to true. The default value is 2.2F.
- ///
- /// The gamma value of the image.
- public float Gamma { get; set; } = 2.2F;
-
- ///
- /// The quantizer for reducing the color count.
- ///
- public IQuantizer Quantizer { get; set; }
-
- ///
- /// Gets or sets the transparency threshold.
- ///
- public byte Threshold { get; set; } = 128;
-
- ///
- public void Encode(ImageBase image, Stream stream)
- {
- Guard.NotNull(image, nameof(image));
- Guard.NotNull(stream, nameof(stream));
-
- // Write the png header.
- stream.Write(
- new byte[]
- {
- 0x89, // Set the high bit.
- 0x50, // P
- 0x4E, // N
- 0x47, // G
- 0x0D, // Line ending CRLF
- 0x0A, // Line ending CRLF
- 0x1A, // EOF
- 0x0A // LF
- },
- 0,
- 8);
-
- // Ensure that quality can be set but has a fallback.
- int quality = this.Quality > 0 ? this.Quality : image.Quality;
- this.Quality = quality > 0 ? quality.Clamp(1, int.MaxValue) : int.MaxValue;
-
- this.bitDepth = this.Quality <= 256
- ? (byte)(ImageMaths.GetBitsNeededForColorDepth(this.Quality).Clamp(1, 8))
- : (byte)8;
-
- // Png only supports in four pixel depths: 1, 2, 4, and 8 bits when using the PLTE chunk
- if (this.bitDepth == 3)
- {
- this.bitDepth = 4;
- }
- else if (this.bitDepth >= 5 || this.bitDepth <= 7)
- {
- this.bitDepth = 8;
- }
-
- // TODO: Add more color options here.
- PngHeader header = new PngHeader
- {
- Width = image.Width,
- Height = image.Height,
- ColorType = (byte)(this.Quality <= 256 ? 3 : 6), // 3 = indexed, 6= Each pixel is an R,G,B triple, followed by an alpha sample.
- BitDepth = this.bitDepth,
- FilterMethod = 0, // None
- CompressionMethod = 0,
- InterlaceMethod = 0
- };
-
- this.WriteHeaderChunk(stream, header);
- this.WritePaletteChunk(stream, header, image);
- this.WritePhysicalChunk(stream, image);
- this.WriteGammaChunk(stream);
-
- using (PixelAccessor pixels = image.Lock())
- {
- this.WriteDataChunks(stream, pixels);
- }
-
- this.WriteEndChunk(stream);
- stream.Flush();
- }
-
- ///
- /// Writes an integer to the byte array.
- ///
- /// The containing image data.
- /// The amount to offset by.
- /// The value to write.
- private static void WriteInteger(byte[] data, int offset, int value)
- {
- byte[] buffer = BitConverter.GetBytes(value);
-
- Array.Reverse(buffer);
- Array.Copy(buffer, 0, data, offset, 4);
- }
-
- ///
- /// Writes an integer to the stream.
- ///
- /// The containing image data.
- /// The value to write.
- private static void WriteInteger(Stream stream, int value)
- {
- byte[] buffer = BitConverter.GetBytes(value);
-
- Array.Reverse(buffer);
-
- stream.Write(buffer, 0, 4);
- }
-
- ///
- /// Writes an unsigned integer to the stream.
- ///
- /// The containing image data.
- /// The value to write.
- private static void WriteInteger(Stream stream, uint value)
- {
- byte[] buffer = BitConverter.GetBytes(value);
-
- Array.Reverse(buffer);
-
- stream.Write(buffer, 0, 4);
- }
-
- ///
- /// Writes the header chunk to the stream.
- ///
- /// The containing image data.
- /// The .
- private void WriteHeaderChunk(Stream stream, PngHeader header)
- {
- byte[] chunkData = new byte[13];
-
- WriteInteger(chunkData, 0, header.Width);
- WriteInteger(chunkData, 4, header.Height);
-
- chunkData[8] = header.BitDepth;
- chunkData[9] = header.ColorType;
- chunkData[10] = header.CompressionMethod;
- chunkData[11] = header.FilterMethod;
- chunkData[12] = header.InterlaceMethod;
-
- this.WriteChunk(stream, PngChunkTypes.Header, chunkData);
- }
-
- ///
- /// Writes the palette chunk to the stream.
- ///
- /// The containing image data.
- /// The .
- /// The image to encode.
- private void WritePaletteChunk(Stream stream, PngHeader header, ImageBase image)
- {
- if (this.Quality > 256)
- {
- return;
- }
-
- if (this.Quantizer == null)
- {
- this.Quantizer = new WuQuantizer { Threshold = this.Threshold };
- }
-
- // Quantize the image returning a palette.
- this.quantized = this.Quantizer.Quantize(image, this.Quality);
-
- // Grab the palette and write it to the stream.
- Bgra32[] palette = this.quantized.Palette;
- int pixelCount = palette.Length;
-
- // Get max colors for bit depth.
- int colorTableLength = (int)Math.Pow(2, header.BitDepth) * 3;
- byte[] colorTable = new byte[colorTableLength];
-
- Parallel.For(0, pixelCount,
- i =>
- {
- int offset = i * 3;
- Bgra32 color = palette[i];
-
- colorTable[offset] = color.R;
- colorTable[offset + 1] = color.G;
- colorTable[offset + 2] = color.B;
- });
-
- this.WriteChunk(stream, PngChunkTypes.Palette, colorTable);
-
- // Write the transparency data
- if (this.quantized.TransparentIndex > -1)
- {
- this.WriteChunk(stream, PngChunkTypes.PaletteAlpha, new[] { (byte)this.quantized.TransparentIndex });
- }
- }
-
- ///
- /// Writes the physical dimension information to the stream.
- ///
- /// The containing image data.
- /// The image base.
- private void WritePhysicalChunk(Stream stream, ImageBase imageBase)
- {
- Image image = imageBase as Image;
- if (image != null && image.HorizontalResolution > 0 && image.VerticalResolution > 0)
- {
- // 39.3700787 = inches in a meter.
- int dpmX = (int)Math.Round(image.HorizontalResolution * 39.3700787d);
- int dpmY = (int)Math.Round(image.VerticalResolution * 39.3700787d);
-
- byte[] chunkData = new byte[9];
-
- WriteInteger(chunkData, 0, dpmX);
- WriteInteger(chunkData, 4, dpmY);
-
- chunkData[8] = 1;
-
- this.WriteChunk(stream, PngChunkTypes.Physical, chunkData);
- }
- }
-
- ///
- /// Writes the gamma information to the stream.
- ///
- /// The containing image data.
- private void WriteGammaChunk(Stream stream)
- {
- if (this.WriteGamma)
- {
- int gammaValue = (int)(this.Gamma * 100000f);
-
- byte[] fourByteData = new byte[4];
-
- byte[] size = BitConverter.GetBytes(gammaValue);
-
- fourByteData[0] = size[3];
- fourByteData[1] = size[2];
- fourByteData[2] = size[1];
- fourByteData[3] = size[0];
-
- this.WriteChunk(stream, PngChunkTypes.Gamma, fourByteData);
- }
- }
-
- ///
- /// Writes the pixel information to the stream.
- ///
- /// The containing image data.
- /// The image pixels.
- private void WriteDataChunks(Stream stream, PixelAccessor pixels)
- {
- byte[] data;
- int imageWidth = pixels.Width;
- int imageHeight = pixels.Height;
-
- // Indexed image.
- if (this.Quality <= 256)
- {
- int rowLength = imageWidth + 1;
- data = new byte[rowLength * imageHeight];
-
- Parallel.For(0, imageHeight, y =>
- {
- int dataOffset = (y * rowLength);
- byte compression = 0;
- if (y > 0)
- {
- compression = 2;
- }
- data[dataOffset++] = compression;
- for (int x = 0; x < imageWidth; x++)
- {
- data[dataOffset++] = this.quantized.Pixels[(y * imageWidth) + x];
- if (y > 0)
- {
- data[dataOffset - 1] -= this.quantized.Pixels[((y - 1) * imageWidth) + x];
- }
- }
- });
- }
- else
- {
- // TrueColor image.
- data = new byte[(imageWidth * imageHeight * 4) + pixels.Height];
-
- int rowLength = (imageWidth * 4) + 1;
-
- Parallel.For(0, imageHeight, y =>
- {
- byte compression = 0;
- if (y > 0)
- {
- compression = 2;
- }
-
- data[y * rowLength] = compression;
-
- for (int x = 0; x < imageWidth; x++)
- {
- Bgra32 color = Color.ToNonPremultiplied(pixels[x, y]);
-
- // Calculate the offset for the new array.
- int dataOffset = (y * rowLength) + (x * 4) + 1;
- data[dataOffset] = color.R;
- data[dataOffset + 1] = color.G;
- data[dataOffset + 2] = color.B;
- data[dataOffset + 3] = color.A;
-
- if (y > 0)
- {
- color = Color.ToNonPremultiplied(pixels[x, y - 1]);
-
- data[dataOffset] -= color.R;
- data[dataOffset + 1] -= color.G;
- data[dataOffset + 2] -= color.B;
- data[dataOffset + 3] -= color.A;
- }
- }
- });
- }
-
- byte[] buffer;
- int bufferLength;
-
- MemoryStream memoryStream = null;
- try
- {
- memoryStream = new MemoryStream();
-
- using (ZlibDeflateStream deflateStream = new ZlibDeflateStream(memoryStream, this.CompressionLevel))
- {
- deflateStream.Write(data, 0, data.Length);
- }
-
- bufferLength = (int)memoryStream.Length;
- buffer = memoryStream.ToArray();
- }
- finally
- {
- memoryStream?.Dispose();
- }
-
- int numChunks = bufferLength / MaxBlockSize;
-
- if (bufferLength % MaxBlockSize != 0)
- {
- numChunks++;
- }
-
- for (int i = 0; i < numChunks; i++)
- {
- int length = bufferLength - (i * MaxBlockSize);
-
- if (length > MaxBlockSize)
- {
- length = MaxBlockSize;
- }
-
- this.WriteChunk(stream, PngChunkTypes.Data, buffer, i * MaxBlockSize, length);
- }
- }
-
- ///
- /// Writes the chunk end to the stream.
- ///
- /// The containing image data.
- private void WriteEndChunk(Stream stream)
- {
- this.WriteChunk(stream, PngChunkTypes.End, null);
- }
-
- ///
- /// Writes a chunk to the stream.
- ///
- /// The to write to.
- /// The type of chunk to write.
- /// The containing data.
- private void WriteChunk(Stream stream, string type, byte[] data)
- {
- this.WriteChunk(stream, type, data, 0, data?.Length ?? 0);
- }
-
- ///
- /// Writes a chunk of a specified length to the stream at the given offset.
- ///
- /// The to write to.
- /// The type of chunk to write.
- /// The containing data.
- /// The position to offset the data at.
- /// The of the data to write.
- private void WriteChunk(Stream stream, string type, byte[] data, int offset, int length)
- {
- WriteInteger(stream, length);
-
- byte[] typeArray = new byte[4];
- typeArray[0] = (byte)type[0];
- typeArray[1] = (byte)type[1];
- typeArray[2] = (byte)type[2];
- typeArray[3] = (byte)type[3];
-
- stream.Write(typeArray, 0, 4);
-
- if (data != null)
- {
- stream.Write(data, offset, length);
- }
-
- Crc32 crc32 = new Crc32();
- crc32.Update(typeArray);
-
- if (data != null)
- {
- crc32.Update(data, offset, length);
- }
-
- WriteInteger(stream, (uint)crc32.Value);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/PngFormat.cs b/src/ImageProcessorCore - Copy/Formats/Png/PngFormat.cs
deleted file mode 100644
index 38a0a7c384..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/PngFormat.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Encapsulates the means to encode and decode png images.
- ///
- public class PngFormat : IImageFormat
- {
- ///
- public IImageDecoder Decoder => new PngDecoder();
-
- ///
- public IImageEncoder Encoder => new PngEncoder();
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/PngHeader.cs b/src/ImageProcessorCore - Copy/Formats/Png/PngHeader.cs
deleted file mode 100644
index dfa30794a8..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/PngHeader.cs
+++ /dev/null
@@ -1,62 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Represents the png header chunk.
- ///
- public sealed class PngHeader
- {
- ///
- /// Gets or sets the dimension in x-direction of the image in pixels.
- ///
- public int Width { get; set; }
-
- ///
- /// Gets or sets the dimension in y-direction of the image in pixels.
- ///
- public int Height { get; set; }
-
- ///
- /// Gets or sets the bit depth.
- /// Bit depth is a single-byte integer giving the number of bits per sample
- /// or per palette index (not per pixel). Valid values are 1, 2, 4, 8, and 16,
- /// although not all values are allowed for all color types.
- ///
- public byte BitDepth { get; set; }
-
- ///
- /// Gets or sets the color type.
- /// Color type is a integer that describes the interpretation of the
- /// image data. Color type codes represent sums of the following values:
- /// 1 (palette used), 2 (color used), and 4 (alpha channel used).
- ///
- public byte ColorType { get; set; }
-
- ///
- /// Gets or sets the compression method.
- /// Indicates the method used to compress the image data. At present,
- /// only compression method 0 (deflate/inflate compression with a sliding
- /// window of at most 32768 bytes) is defined.
- ///
- public byte CompressionMethod { get; set; }
-
- ///
- /// Gets or sets the preprocessing method.
- /// Indicates the preprocessing method applied to the image
- /// data before compression. At present, only filter method 0
- /// (adaptive filtering with five basic filter types) is defined.
- ///
- public byte FilterMethod { get; set; }
-
- ///
- /// Gets or sets the transmission order.
- /// Indicates the transmission order of the image data.
- /// Two values are currently defined: 0 (no interlace) or 1 (Adam7 interlace).
- ///
- public byte InterlaceMethod { get; set; }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/README.md b/src/ImageProcessorCore - Copy/Formats/Png/README.md
deleted file mode 100644
index 8ade379560..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-Encoder/Decoder adapted from:
-
-https://github.com/yufeih/Nine.Imaging/
-https://imagetools.codeplex.com/
-https://github.com/leonbloy/pngcs
-
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/TrueColorReader.cs b/src/ImageProcessorCore - Copy/Formats/Png/TrueColorReader.cs
deleted file mode 100644
index 47c39b029f..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/TrueColorReader.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Color reader for reading true colors from a png file. Only colors
- /// with 24 or 32 bit (3 or 4 bytes) per pixel are supported at the moment.
- ///
- internal sealed class TrueColorReader : IColorReader
- {
- ///
- /// Whether t also read the alpha channel.
- ///
- private readonly bool useAlpha;
-
- ///
- /// The current row.
- ///
- private int row;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// if set to true the color reader will also read the
- /// alpha channel from the scanline.
- public TrueColorReader(bool useAlpha)
- {
- this.useAlpha = useAlpha;
- }
-
- ///
- public void ReadScanline(byte[] scanline, float[] pixels, PngHeader header)
- {
- int offset;
-
- byte[] newScanline = scanline.ToArrayByBitsLength(header.BitDepth);
-
- if (this.useAlpha)
- {
- for (int x = 0; x < newScanline.Length; x += 4)
- {
- offset = ((this.row * header.Width) + (x >> 2)) * 4;
-
- // We want to convert to premultiplied alpha here.
- float r = newScanline[x] / 255f;
- float g = newScanline[x + 1] / 255f;
- float b = newScanline[x + 2] / 255f;
- float a = newScanline[x + 3] / 255f;
-
- Color premultiplied = Color.FromNonPremultiplied(new Color(r, g, b, a));
-
- pixels[offset] = premultiplied.R;
- pixels[offset + 1] = premultiplied.G;
- pixels[offset + 2] = premultiplied.B;
- pixels[offset + 3] = premultiplied.A;
- }
- }
- else
- {
- for (int x = 0; x < newScanline.Length / 3; x++)
- {
- offset = ((this.row * header.Width) + x) * 4;
- int pixelOffset = x * 3;
-
- pixels[offset] = newScanline[pixelOffset] / 255f;
- pixels[offset + 1] = newScanline[pixelOffset + 1] / 255f;
- pixels[offset + 2] = newScanline[pixelOffset + 2] / 255f;
- pixels[offset + 3] = 1;
- }
- }
-
- this.row++;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/Zlib/Adler32.cs b/src/ImageProcessorCore - Copy/Formats/Png/Zlib/Adler32.cs
deleted file mode 100644
index f58ec34c2d..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/Zlib/Adler32.cs
+++ /dev/null
@@ -1,174 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
-
- ///
- /// Computes Adler32 checksum for a stream of data. An Adler32
- /// checksum is not as reliable as a CRC32 checksum, but a lot faster to
- /// compute.
- ///
- ///
- /// The specification for Adler32 may be found in RFC 1950.
- /// ZLIB Compressed Data Format Specification version 3.3)
- ///
- ///
- /// From that document:
- ///
- /// "ADLER32 (Adler-32 checksum)
- /// This contains a checksum value of the uncompressed data
- /// (excluding any dictionary data) computed according to Adler-32
- /// algorithm. This algorithm is a 32-bit extension and improvement
- /// of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
- /// standard.
- ///
- /// Adler-32 is composed of two sums accumulated per byte: s1 is
- /// the sum of all bytes, s2 is the sum of all s1 values. Both sums
- /// are done modulo 65521. s1 is initialized to 1, s2 to zero. The
- /// Adler-32 checksum is stored as s2*65536 + s1 in most-
- /// significant-byte first (network) order."
- ///
- /// "8.2. The Adler-32 algorithm
- ///
- /// The Adler-32 algorithm is much faster than the CRC32 algorithm yet
- /// still provides an extremely low probability of undetected errors.
- ///
- /// The modulo on unsigned long accumulators can be delayed for 5552
- /// bytes, so the modulo operation time is negligible. If the bytes
- /// are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
- /// and order sensitive, unlike the first sum, which is just a
- /// checksum. That 65521 is prime is important to avoid a possible
- /// large class of two-byte errors that leave the check unchanged.
- /// (The Fletcher checksum uses 255, which is not prime and which also
- /// makes the Fletcher check insensitive to single byte changes 0 -
- /// 255.)
- ///
- /// The sum s1 is initialized to 1 instead of zero to make the length
- /// of the sequence part of s2, so that the length does not have to be
- /// checked separately. (Any sequence of zeroes has a Fletcher
- /// checksum of zero.)"
- ///
- ///
- ///
- internal sealed class Adler32 : IChecksum
- {
- ///
- /// largest prime smaller than 65536
- ///
- private const uint Base = 65521;
-
- ///
- /// The checksum calculated to far.
- ///
- private uint checksum;
-
- ///
- /// Initializes a new instance of the class.
- /// The checksum starts off with a value of 1.
- ///
- public Adler32()
- {
- this.Reset();
- }
-
- ///
- public long Value => this.checksum;
-
- ///
- public void Reset()
- {
- this.checksum = 1;
- }
-
- ///
- /// Updates the checksum with a byte value.
- ///
- ///
- /// The data value to add. The high byte of the int is ignored.
- ///
- public void Update(int value)
- {
- // We could make a length 1 byte array and call update again, but I
- // would rather not have that overhead
- uint s1 = this.checksum & 0xFFFF;
- uint s2 = this.checksum >> 16;
-
- s1 = (s1 + ((uint)value & 0xFF)) % Base;
- s2 = (s1 + s2) % Base;
-
- this.checksum = (s2 << 16) + s1;
- }
-
- ///
- public void Update(byte[] buffer)
- {
- if (buffer == null)
- {
- throw new ArgumentNullException(nameof(buffer));
- }
-
- this.Update(buffer, 0, buffer.Length);
- }
-
- ///
- public void Update(byte[] buffer, int offset, int count)
- {
- if (buffer == null)
- {
- throw new ArgumentNullException(nameof(buffer));
- }
-
- if (offset < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(offset), "cannot be negative");
- }
-
- if (count < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(count), "cannot be negative");
- }
-
- if (offset >= buffer.Length)
- {
- throw new ArgumentOutOfRangeException(nameof(offset), "not a valid index into buffer");
- }
-
- if (offset + count > buffer.Length)
- {
- throw new ArgumentOutOfRangeException(nameof(count), "exceeds buffer size");
- }
-
- // (By Per Bothner)
- uint s1 = this.checksum & 0xFFFF;
- uint s2 = this.checksum >> 16;
-
- while (count > 0)
- {
- // We can defer the modulo operation:
- // s1 maximally grows from 65521 to 65521 + 255 * 3800
- // s2 maximally grows by 3800 * median(s1) = 2090079800 < 2^31
- int n = 3800;
- if (n > count)
- {
- n = count;
- }
-
- count -= n;
- while (--n >= 0)
- {
- s1 = s1 + (uint)(buffer[offset++] & 0xff);
- s2 = s2 + s1;
- }
-
- s1 %= Base;
- s2 %= Base;
- }
-
- this.checksum = (s2 << 16) | s1;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/Zlib/Crc32.cs b/src/ImageProcessorCore - Copy/Formats/Png/Zlib/Crc32.cs
deleted file mode 100644
index da42e8dae4..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/Zlib/Crc32.cs
+++ /dev/null
@@ -1,180 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
-
- ///
- /// Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
- /// x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
- ///
- ///
- ///
- /// Polynomials over GF(2) are represented in binary, one bit per coefficient,
- /// with the lowest powers in the most significant bit. Then adding polynomials
- /// is just exclusive-or, and multiplying a polynomial by x is a right shift by
- /// one. If we call the above polynomial p, and represent a byte as the
- /// polynomial q, also with the lowest power in the most significant bit (so the
- /// byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
- /// where a mod b means the remainder after dividing a by b.
- ///
- ///
- /// This calculation is done using the shift-register method of multiplying and
- /// taking the remainder. The register is initialized to zero, and for each
- /// incoming bit, x^32 is added mod p to the register if the bit is a one (where
- /// x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
- /// x (which is shifting right by one and adding x^32 mod p if the bit shifted
- /// out is a one). We start with the highest power (least significant bit) of
- /// q and repeat for all eight bits of q.
- ///
- ///
- /// The table is simply the CRC of all possible eight bit values. This is all
- /// the information needed to generate CRC's on data a byte at a time for all
- /// combinations of CRC register values and incoming bytes.
- ///
- ///
- internal sealed class Crc32 : IChecksum
- {
- ///
- /// The cycle redundancy check seed
- ///
- private const uint CrcSeed = 0xFFFFFFFF;
-
- ///
- /// The table of all possible eight bit values for fast lookup.
- ///
- private static readonly uint[] CrcTable =
- {
- 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419,
- 0x706AF48F, 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4,
- 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07,
- 0x90BF1D91, 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
- 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856,
- 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
- 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4,
- 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
- 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3,
- 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A,
- 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599,
- 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
- 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190,
- 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
- 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2, 0x0F00F934, 0x9609A88E,
- 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
- 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED,
- 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
- 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3,
- 0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
- 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A,
- 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
- 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010,
- 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
- 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17,
- 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6,
- 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615,
- 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
- 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344,
- 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
- 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A,
- 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
- 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1,
- 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C,
- 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF,
- 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
- 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE,
- 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
- 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226, 0x756AA39C,
- 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
- 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B,
- 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
- 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1,
- 0x18B74777, 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
- 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278,
- 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
- 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66,
- 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
- 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605,
- 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8,
- 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B,
- 0x2D02EF8D
- };
-
- ///
- /// The data checksum so far.
- ///
- private uint crc;
-
- ///
- public long Value
- {
- get
- {
- return this.crc;
- }
-
- set
- {
- this.crc = (uint)value;
- }
- }
-
- ///
- public void Reset()
- {
- this.crc = 0;
- }
-
- ///
- /// Updates the checksum with the given value.
- ///
- /// The byte is taken as the lower 8 bits of value.
- public void Update(int value)
- {
- this.crc ^= CrcSeed;
- this.crc = CrcTable[(this.crc ^ value) & 0xFF] ^ (this.crc >> 8);
- this.crc ^= CrcSeed;
- }
-
- ///
- public void Update(byte[] buffer)
- {
- if (buffer == null)
- {
- throw new ArgumentNullException(nameof(buffer));
- }
-
- this.Update(buffer, 0, buffer.Length);
- }
-
- ///
- public void Update(byte[] buffer, int offset, int count)
- {
- if (buffer == null)
- {
- throw new ArgumentNullException(nameof(buffer));
- }
-
- if (count < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(count), "Count cannot be less than zero");
- }
-
- if (offset < 0 || offset + count > buffer.Length)
- {
- throw new ArgumentOutOfRangeException(nameof(offset));
- }
-
- this.crc ^= CrcSeed;
-
- while (--count >= 0)
- {
- this.crc = CrcTable[(this.crc ^ buffer[offset++]) & 0xFF] ^ (this.crc >> 8);
- }
-
- this.crc ^= CrcSeed;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/Zlib/IChecksum.cs b/src/ImageProcessorCore - Copy/Formats/Png/Zlib/IChecksum.cs
deleted file mode 100644
index 077a5ad2a6..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/Zlib/IChecksum.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- ///
- /// Interface to compute a data checksum used by checked input/output streams.
- /// A data checksum can be updated by one byte or with a byte array. After each
- /// update the value of the current checksum can be returned by calling
- /// Value. The complete checksum object can also be reset
- /// so it can be used again with new data.
- ///
- public interface IChecksum
- {
- ///
- /// Gets the data checksum computed so far.
- ///
- long Value
- {
- get;
- }
-
- ///
- /// Resets the data checksum as if no update was ever called.
- ///
- void Reset();
-
- ///
- /// Adds one byte to the data checksum.
- ///
- ///
- /// The data value to add. The high byte of the integer is ignored.
- ///
- void Update(int value);
-
- ///
- /// Updates the data checksum with the bytes taken from the array.
- ///
- ///
- /// buffer an array of bytes
- ///
- void Update(byte[] buffer);
-
- ///
- /// Adds the byte array to the data checksum.
- ///
- ///
- /// The buffer which contains the data
- ///
- ///
- /// The offset in the buffer where the data starts
- ///
- ///
- /// the number of data bytes to add.
- ///
- void Update(byte[] buffer, int offset, int count);
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/Zlib/README.md b/src/ImageProcessorCore - Copy/Formats/Png/Zlib/README.md
deleted file mode 100644
index c297a91d5e..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/Zlib/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-Adler32.cs and Crc32.cs have been copied from
-https://github.com/ygrenier/SharpZipLib.Portable
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/Zlib/ZlibDeflateStream.cs b/src/ImageProcessorCore - Copy/Formats/Png/Zlib/ZlibDeflateStream.cs
deleted file mode 100644
index a2c0ca202f..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/Zlib/ZlibDeflateStream.cs
+++ /dev/null
@@ -1,210 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
- using System.IO.Compression;
-
- ///
- /// Provides methods and properties for compressing streams by using the Zlib Deflate algorithm.
- ///
- internal sealed class ZlibDeflateStream : Stream
- {
- ///
- /// The raw stream containing the uncompressed image data.
- ///
- private readonly Stream rawStream;
-
- ///
- /// Computes the checksum for the data stream.
- ///
- private readonly Adler32 adler32 = new Adler32();
-
- ///
- /// 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;
-
- // The stream responsible for decompressing the input stream.
- private DeflateStream deflateStream;
-
- ///
- /// Initializes a new instance of
- ///
- /// The stream to compress.
- /// The compression level.
- public ZlibDeflateStream(Stream stream, int compressionLevel)
- {
- this.rawStream = stream;
-
- // Write the zlib header : http://tools.ietf.org/html/rfc1950
- // CMF(Compression Method and flags)
- // This byte is divided into a 4 - bit compression method and a
- // 4-bit information field depending on the compression method.
- // bits 0 to 3 CM Compression method
- // bits 4 to 7 CINFO Compression info
- //
- // 0 1
- // +---+---+
- // |CMF|FLG|
- // +---+---+
- int cmf = 0x78;
- int flg = 218;
-
- // http://stackoverflow.com/a/2331025/277304
- if (compressionLevel >= 5 && compressionLevel <= 6)
- {
- flg = 156;
- }
- else if (compressionLevel >= 3 && compressionLevel <= 4)
- {
- flg = 94;
- }
-
- else if (compressionLevel <= 2)
- {
- flg = 1;
- }
-
- // Just in case
- flg -= (cmf * 256 + flg) % 31;
-
- if (flg < 0)
- {
- flg += 31;
- }
-
- this.rawStream.WriteByte((byte)cmf);
- this.rawStream.WriteByte((byte)flg);
-
- // Initialize the deflate Stream.
- CompressionLevel level = CompressionLevel.Optimal;
-
- if (compressionLevel >= 1 && compressionLevel <= 5)
- {
- level = CompressionLevel.Fastest;
- }
-
- else if (compressionLevel == 0)
- {
- level = CompressionLevel.NoCompression;
- }
-
- this.deflateStream = new DeflateStream(this.rawStream, level, true);
- }
-
- ///
- public override bool CanRead => false;
-
- ///
- public override bool CanSeek => false;
-
- ///
- public override bool CanWrite => true;
-
- ///
- public override long Length
- {
- get
- {
- throw new NotSupportedException();
- }
- }
-
- ///
- public override long Position
- {
- get
- {
- throw new NotSupportedException();
- }
-
- set
- {
- throw new NotSupportedException();
- }
- }
-
- ///
- public override void Flush()
- {
- this.deflateStream?.Flush();
- }
-
- ///
- public override int Read(byte[] buffer, int offset, int count)
- {
- throw new NotSupportedException();
- }
-
- ///
- public override long Seek(long offset, SeekOrigin origin)
- {
- throw new NotSupportedException();
- }
-
- ///
- public override void SetLength(long value)
- {
- throw new NotSupportedException();
- }
-
- ///
- public override void Write(byte[] buffer, int offset, int count)
- {
- this.deflateStream.Write(buffer, offset, count);
- this.adler32.Update(buffer, offset, count);
- }
-
- ///
- protected override void Dispose(bool disposing)
- {
- if (this.isDisposed)
- {
- return;
- }
-
- if (disposing)
- {
- // dispose managed resources
- if (this.deflateStream != null)
- {
- this.deflateStream.Dispose();
- this.deflateStream = null;
- }
- else {
-
- // Hack: empty input?
- this.rawStream.WriteByte(3);
- this.rawStream.WriteByte(0);
- }
-
- // Add the crc
- uint crc = (uint)this.adler32.Value;
- this.rawStream.WriteByte((byte)((crc >> 24) & 0xFF));
- this.rawStream.WriteByte((byte)((crc >> 16) & 0xFF));
- this.rawStream.WriteByte((byte)((crc >> 8) & 0xFF));
- this.rawStream.WriteByte((byte)((crc) & 0xFF));
- }
-
- base.Dispose(disposing);
-
- // Call the appropriate methods to clean up
- // unmanaged resources here.
- // Note disposing is done.
- this.isDisposed = true;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Formats/Png/Zlib/ZlibInflateStream.cs b/src/ImageProcessorCore - Copy/Formats/Png/Zlib/ZlibInflateStream.cs
deleted file mode 100644
index 4373b5fd17..0000000000
--- a/src/ImageProcessorCore - Copy/Formats/Png/Zlib/ZlibInflateStream.cs
+++ /dev/null
@@ -1,205 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Formats
-{
- using System;
- using System.IO;
- using System.IO.Compression;
-
- ///
- /// Provides methods and properties for decompressing streams by using the Zlib Deflate algorithm.
- ///
- internal sealed class ZlibInflateStream : Stream
- {
- ///
- /// 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;
-
- ///
- /// The raw stream containing the uncompressed image data.
- ///
- private readonly Stream rawStream;
-
- ///
- /// The read crc data.
- ///
- private byte[] crcread;
-
- // The stream responsible for decompressing the input stream.
- private DeflateStream deflateStream;
-
- public ZlibInflateStream(Stream stream)
- {
- // The DICT dictionary identifier identifying the used dictionary.
-
- // The preset dictionary.
- bool fdict;
- this.rawStream = stream;
-
- // Read the zlib header : http://tools.ietf.org/html/rfc1950
- // CMF(Compression Method and flags)
- // This byte is divided into a 4 - bit compression method and a
- // 4-bit information field depending on the compression method.
- // bits 0 to 3 CM Compression method
- // bits 4 to 7 CINFO Compression info
- //
- // 0 1
- // +---+---+
- // |CMF|FLG|
- // +---+---+
- int cmf = this.rawStream.ReadByte();
- int flag = this.rawStream.ReadByte();
- if (cmf == -1 || flag == -1)
- {
- return;
- }
-
- if ((cmf & 0x0f) != 8)
- {
- throw new Exception($"Bad compression method for ZLIB header: cmf={cmf}");
- }
-
- // CINFO is the base-2 logarithm of the LZ77 window size, minus eight.
- // int cinfo = ((cmf & (0xf0)) >> 8);
- fdict = (flag & 32) != 0;
-
- if (fdict)
- {
- // The DICT dictionary identifier identifying the used dictionary.
- byte[] dictId = new byte[4];
-
- for (int i = 0; i < 4; i++)
- {
- // We consume but don't use this.
- dictId[i] = (byte)this.rawStream.ReadByte();
- }
- }
-
- // Initialize the deflate Stream.
- this.deflateStream = new DeflateStream(this.rawStream, CompressionMode.Decompress, true);
- }
-
- ///
- public override bool CanRead => true;
-
- ///
- public override bool CanSeek => false;
-
- ///
- public override bool CanWrite => false;
-
- ///
- public override long Length
- {
- get
- {
- throw new NotSupportedException();
- }
- }
-
- ///
- public override long Position
- {
- get
- {
- throw new NotSupportedException();
- }
-
- set
- {
- throw new NotSupportedException();
- }
- }
-
- ///
- public override void Flush()
- {
- this.deflateStream?.Flush();
- }
-
- ///
- public override int Read(byte[] buffer, int offset, int count)
- {
- // We dont't check CRC on reading
- int read = this.deflateStream.Read(buffer, offset, count);
- if (read < 1 && this.crcread == null)
- {
- // The deflater has ended. We try to read the next 4 bytes from raw stream (crc)
- this.crcread = new byte[4];
- for (int i = 0; i < 4; i++)
- {
- // we dont really check/use this
- this.crcread[i] = (byte)this.rawStream.ReadByte();
- }
- }
-
- return read;
- }
-
- ///
- public override long Seek(long offset, SeekOrigin origin)
- {
- throw new NotSupportedException();
- }
-
- ///
- public override void SetLength(long value)
- {
- throw new NotSupportedException();
- }
-
- ///
- public override void Write(byte[] buffer, int offset, int count)
- {
- throw new NotSupportedException();
- }
-
- ///
- protected override void Dispose(bool disposing)
- {
- if (this.isDisposed)
- {
- return;
- }
-
- if (disposing)
- {
- // dispose managed resources
- if (this.deflateStream != null)
- {
- this.deflateStream.Dispose();
- this.deflateStream = null;
-
- if (this.crcread == null)
- {
- // Consume the trailing 4 bytes
- this.crcread = new byte[4];
- for (int i = 0; i < 4; i++)
- {
- this.crcread[i] = (byte)this.rawStream.ReadByte();
- }
- }
- }
- }
-
- base.Dispose(disposing);
-
- // Call the appropriate methods to clean up
- // unmanaged resources here.
- // Note disposing is done.
- this.isDisposed = true;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/IImageBase.cs b/src/ImageProcessorCore - Copy/IImageBase.cs
deleted file mode 100644
index a721033770..0000000000
--- a/src/ImageProcessorCore - Copy/IImageBase.cs
+++ /dev/null
@@ -1,29 +0,0 @@
-namespace ImageProcessorCore
-{
- public interface IImageBase
- where TPackedVector : IPackedVector
- {
- Rectangle Bounds { get; }
- int FrameDelay { get; set; }
- int Height { get; }
- double PixelRatio { get; }
- TPackedVector[] Pixels { get; }
- int Quality { get; set; }
-
- ///
- /// Gets or sets the maximum allowable width in pixels.
- ///
- int MaxWidth { get; set; }
-
- ///
- /// Gets or sets the maximum allowable height in pixels.
- ///
- int MaxHeight { get; set; }
-
- int Width { get; }
-
- void ClonePixels(int width, int height, TPackedVector[] pixels);
- IPixelAccessor Lock();
- void SetPixels(int width, int height, TPackedVector[] pixels);
- }
-}
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/IImageFrame.cs b/src/ImageProcessorCore - Copy/IImageFrame.cs
deleted file mode 100644
index 1565879a76..0000000000
--- a/src/ImageProcessorCore - Copy/IImageFrame.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-namespace ImageProcessorCore
-{
- public interface IImageFrame : IImageBase
- where TPacked : IPackedVector
- {
- }
-}
diff --git a/src/ImageProcessorCore - Copy/IImageProcessor.cs b/src/ImageProcessorCore - Copy/IImageProcessor.cs
deleted file mode 100644
index ad6e4ac761..0000000000
--- a/src/ImageProcessorCore - Copy/IImageProcessor.cs
+++ /dev/null
@@ -1,72 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// 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 TPackedVector : IPackedVector;
-
- ///
- /// 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 TPackedVector : IPackedVector;
- }
-}
diff --git a/src/ImageProcessorCore - Copy/IO/BigEndianBitConverter.cs b/src/ImageProcessorCore - Copy/IO/BigEndianBitConverter.cs
deleted file mode 100644
index 6c624c6a6b..0000000000
--- a/src/ImageProcessorCore - Copy/IO/BigEndianBitConverter.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.IO
-{
- ///
- /// Implementation of EndianBitConverter which converts to/from big-endian
- /// byte arrays.
- ///
- /// Adapted from Miscellaneous Utility Library
- /// This product includes software developed by Jon Skeet and Marc Gravell. Contact , or see
- /// .
- ///
- ///
- internal sealed class BigEndianBitConverter : EndianBitConverter
- {
- ///
- public override Endianness Endianness => Endianness.BigEndian;
-
- ///
- public override bool IsLittleEndian() => false;
-
- ///
- protected internal override void CopyBytesImpl(long value, int bytes, byte[] buffer, int index)
- {
- int endOffset = index + bytes - 1;
- for (int i = 0; i < bytes; i++)
- {
- buffer[endOffset - i] = unchecked((byte)(value & 0xff));
- value = value >> 8;
- }
- }
-
- ///
- protected internal override long FromBytes(byte[] buffer, int startIndex, int bytesToConvert)
- {
- long ret = 0;
- for (int i = 0; i < bytesToConvert; i++)
- {
- ret = unchecked((ret << 8) | buffer[startIndex + i]);
- }
-
- return ret;
- }
- }
-}
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/IO/EndianBinaryReader.cs b/src/ImageProcessorCore - Copy/IO/EndianBinaryReader.cs
deleted file mode 100644
index e2fc14a050..0000000000
--- a/src/ImageProcessorCore - Copy/IO/EndianBinaryReader.cs
+++ /dev/null
@@ -1,616 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.IO
-{
- using System;
- using System.IO;
- using System.Text;
-
- ///
- /// Equivalent of , but with either endianness, depending on
- /// the EndianBitConverter it is constructed with. No data is buffered in the
- /// reader; the client may seek within the stream at will.
- ///
- internal class EndianBinaryReader : IDisposable
- {
- ///
- /// Decoder to use for string conversions.
- ///
- private readonly Decoder decoder;
-
- ///
- /// Buffer used for temporary storage before conversion into primitives
- ///
- private readonly byte[] buffer = new byte[16];
-
- ///
- /// Buffer used for temporary storage when reading a single character
- ///
- private readonly char[] charBuffer = new char[1];
-
- ///
- /// Minimum number of bytes used to encode a character
- ///
- private readonly int minBytesPerChar;
-
- ///
- /// Whether or not this reader has been disposed yet.
- ///
- private bool disposed;
-
- ///
- /// Equivalent of System.IO.BinaryWriter, but with either endianness, depending on
- /// the EndianBitConverter it is constructed with.
- ///
- /// Converter to use when reading data
- /// Stream to read data from
- public EndianBinaryReader(EndianBitConverter bitConverter, Stream stream)
- : this(bitConverter, stream, Encoding.UTF8)
- {
- }
-
- ///
- /// Constructs a new binary reader with the given bit converter, reading
- /// to the given stream, using the given encoding.
- ///
- /// Converter to use when reading data
- /// Stream to read data from
- /// Encoding to use when reading character data
- public EndianBinaryReader(EndianBitConverter bitConverter, Stream stream, Encoding encoding)
- {
- // TODO: Use Guard
- if (bitConverter == null)
- {
- throw new ArgumentNullException("bitConverter");
- }
-
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
-
- if (encoding == null)
- {
- throw new ArgumentNullException("encoding");
- }
-
- if (!stream.CanRead)
- {
- throw new ArgumentException("Stream isn't writable", "stream");
- }
-
- this.BaseStream = stream;
- this.BitConverter = bitConverter;
- this.Encoding = encoding;
- this.decoder = encoding.GetDecoder();
- this.minBytesPerChar = 1;
-
- if (encoding is UnicodeEncoding)
- {
- this.minBytesPerChar = 2;
- }
- }
-
- ///
- /// Gets the bit converter used to read values from the stream.
- ///
- public EndianBitConverter BitConverter { get; }
-
- ///
- /// Gets the encoding used to read strings
- ///
- public Encoding Encoding { get; }
-
- ///
- /// Gets the underlying stream of the EndianBinaryReader.
- ///
- public Stream BaseStream { get; }
-
- ///
- /// Closes the reader, including the underlying stream.
- ///
- public void Close()
- {
- this.Dispose();
- }
-
- ///
- /// Seeks within the stream.
- ///
- /// Offset to seek to.
- /// Origin of seek operation.
- public void Seek(int offset, SeekOrigin origin)
- {
- this.CheckDisposed();
- this.BaseStream.Seek(offset, origin);
- }
-
- ///
- /// Reads a single byte from the stream.
- ///
- /// The byte read
- public byte ReadByte()
- {
- this.ReadInternal(this.buffer, 1);
- return this.buffer[0];
- }
-
- ///
- /// Reads a single signed byte from the stream.
- ///
- /// The byte read
- public sbyte ReadSByte()
- {
- this.ReadInternal(this.buffer, 1);
- return unchecked((sbyte)this.buffer[0]);
- }
-
- ///
- /// Reads a boolean from the stream. 1 byte is read.
- ///
- /// The boolean read
- public bool ReadBoolean()
- {
- this.ReadInternal(this.buffer, 1);
- return this.BitConverter.ToBoolean(this.buffer, 0);
- }
-
- ///
- /// Reads a 16-bit signed integer from the stream, using the bit converter
- /// for this reader. 2 bytes are read.
- ///
- /// The 16-bit integer read
- public short ReadInt16()
- {
- this.ReadInternal(this.buffer, 2);
- return this.BitConverter.ToInt16(this.buffer, 0);
- }
-
- ///
- /// Reads a 32-bit signed integer from the stream, using the bit converter
- /// for this reader. 4 bytes are read.
- ///
- /// The 32-bit integer read
- public int ReadInt32()
- {
- this.ReadInternal(this.buffer, 4);
- return this.BitConverter.ToInt32(this.buffer, 0);
- }
-
- ///
- /// Reads a 64-bit signed integer from the stream, using the bit converter
- /// for this reader. 8 bytes are read.
- ///
- /// The 64-bit integer read
- public long ReadInt64()
- {
- this.ReadInternal(this.buffer, 8);
- return this.BitConverter.ToInt64(this.buffer, 0);
- }
-
- ///
- /// Reads a 16-bit unsigned integer from the stream, using the bit converter
- /// for this reader. 2 bytes are read.
- ///
- /// The 16-bit unsigned integer read
- public ushort ReadUInt16()
- {
- this.ReadInternal(this.buffer, 2);
- return this.BitConverter.ToUInt16(this.buffer, 0);
- }
-
- ///
- /// Reads a 32-bit unsigned integer from the stream, using the bit converter
- /// for this reader. 4 bytes are read.
- ///
- /// The 32-bit unsigned integer read
- public uint ReadUInt32()
- {
- this.ReadInternal(this.buffer, 4);
- return this.BitConverter.ToUInt32(this.buffer, 0);
- }
-
- ///
- /// Reads a 64-bit unsigned integer from the stream, using the bit converter
- /// for this reader. 8 bytes are read.
- ///
- /// The 64-bit unsigned integer read
- public ulong ReadUInt64()
- {
- this.ReadInternal(this.buffer, 8);
- return this.BitConverter.ToUInt64(this.buffer, 0);
- }
-
- ///
- /// Reads a single-precision floating-point value from the stream, using the bit converter
- /// for this reader. 4 bytes are read.
- ///
- /// The floating point value read
- public float ReadSingle()
- {
- this.ReadInternal(this.buffer, 4);
- return this.BitConverter.ToSingle(this.buffer, 0);
- }
-
- ///
- /// Reads a double-precision floating-point value from the stream, using the bit converter
- /// for this reader. 8 bytes are read.
- ///
- /// The floating point value read
- public double ReadDouble()
- {
- this.ReadInternal(this.buffer, 8);
- return this.BitConverter.ToDouble(this.buffer, 0);
- }
-
- ///
- /// Reads a decimal value from the stream, using the bit converter
- /// for this reader. 16 bytes are read.
- ///
- /// The decimal value read
- public decimal ReadDecimal()
- {
- this.ReadInternal(this.buffer, 16);
- return this.BitConverter.ToDecimal(this.buffer, 0);
- }
-
- ///
- /// Reads a single character from the stream, using the character encoding for
- /// this reader. If no characters have been fully read by the time the stream ends,
- /// -1 is returned.
- ///
- /// The character read, or -1 for end of stream.
- public int Read()
- {
- int charsRead = this.Read(this.charBuffer, 0, 1);
- if (charsRead == 0)
- {
- return -1;
- }
- else
- {
- return this.charBuffer[0];
- }
- }
-
- ///
- /// Reads the specified number of characters into the given buffer, starting at
- /// the given index.
- ///
- /// The buffer to copy data into
- /// The first index to copy data into
- /// The number of characters to read
- /// The number of characters actually read. This will only be less than
- /// the requested number of characters if the end of the stream is reached.
- ///
- public int Read(char[] data, int index, int count)
- {
- this.CheckDisposed();
-
- // TODO: Use Guard
- if (this.buffer == null)
- {
- throw new ArgumentNullException("buffer");
- }
-
- if (index < 0)
- {
- throw new ArgumentOutOfRangeException("index");
- }
-
- if (count < 0)
- {
- throw new ArgumentOutOfRangeException("index");
- }
-
- if (count + index > data.Length)
- {
- throw new ArgumentException("Not enough space in buffer for specified number of characters starting at specified index");
- }
-
- int read = 0;
- bool firstTime = true;
-
- // Use the normal buffer if we're only reading a small amount, otherwise
- // use at most 4K at a time.
- byte[] byteBuffer = this.buffer;
-
- if (byteBuffer.Length < count * this.minBytesPerChar)
- {
- byteBuffer = new byte[4096];
- }
-
- while (read < count)
- {
- int amountToRead;
-
- // First time through we know we haven't previously read any data
- if (firstTime)
- {
- amountToRead = count * this.minBytesPerChar;
- firstTime = false;
- }
-
- // After that we can only assume we need to fully read 'chars left -1' characters
- // and a single byte of the character we may be in the middle of
- else
- {
- amountToRead = ((count - read - 1) * this.minBytesPerChar) + 1;
- }
-
- if (amountToRead > byteBuffer.Length)
- {
- amountToRead = byteBuffer.Length;
- }
-
- int bytesRead = this.TryReadInternal(byteBuffer, amountToRead);
- if (bytesRead == 0)
- {
- return read;
- }
-
- int decoded = this.decoder.GetChars(byteBuffer, 0, bytesRead, data, index);
- read += decoded;
- index += decoded;
- }
-
- return read;
- }
-
- ///
- /// Reads the specified number of bytes into the given buffer, starting at
- /// the given index.
- ///
- /// The buffer to copy data into
- /// The first index to copy data into
- /// The number of bytes to read
- /// The number of bytes actually read. This will only be less than
- /// the requested number of bytes if the end of the stream is reached.
- ///
- public int Read(byte[] buffer, int index, int count)
- {
- this.CheckDisposed();
- if (buffer == null)
- {
- throw new ArgumentNullException("buffer");
- }
-
- if (index < 0)
- {
- throw new ArgumentOutOfRangeException("index");
- }
-
- if (count < 0)
- {
- throw new ArgumentOutOfRangeException("index");
- }
-
- if (count + index > buffer.Length)
- {
- throw new ArgumentException("Not enough space in buffer for specified number of bytes starting at specified index");
- }
-
- int read = 0;
- while (count > 0)
- {
- int block = this.BaseStream.Read(buffer, index, count);
- if (block == 0)
- {
- return read;
- }
-
- index += block;
- read += block;
- count -= block;
- }
-
- return read;
- }
-
- ///
- /// Reads the specified number of bytes, returning them in a new byte array.
- /// If not enough bytes are available before the end of the stream, this
- /// method will return what is available.
- ///
- /// The number of bytes to read
- /// The bytes read
- public byte[] ReadBytes(int count)
- {
- this.CheckDisposed();
- if (count < 0)
- {
- throw new ArgumentOutOfRangeException("count");
- }
-
- byte[] ret = new byte[count];
- int index = 0;
- while (index < count)
- {
- int read = this.BaseStream.Read(ret, index, count - index);
-
- // Stream has finished half way through. That's fine, return what we've got.
- if (read == 0)
- {
- byte[] copy = new byte[index];
- Buffer.BlockCopy(ret, 0, copy, 0, index);
- return copy;
- }
-
- index += read;
- }
-
- return ret;
- }
-
- ///
- /// Reads the specified number of bytes, returning them in a new byte array.
- /// If not enough bytes are available before the end of the stream, this
- /// method will throw an IOException.
- ///
- /// The number of bytes to read
- /// The bytes read
- public byte[] ReadBytesOrThrow(int count)
- {
- byte[] ret = new byte[count];
- this.ReadInternal(ret, count);
- return ret;
- }
-
- ///
- /// Reads a 7-bit encoded integer from the stream. This is stored with the least significant
- /// information first, with 7 bits of information per byte of value, and the top
- /// bit as a continuation flag. This method is not affected by the endianness
- /// of the bit converter.
- ///
- /// The 7-bit encoded integer read from the stream.
- public int Read7BitEncodedInt()
- {
- this.CheckDisposed();
-
- int ret = 0;
- for (int shift = 0; shift < 35; shift += 7)
- {
- int b = this.BaseStream.ReadByte();
- if (b == -1)
- {
- throw new EndOfStreamException();
- }
-
- ret = ret | ((b & 0x7f) << shift);
- if ((b & 0x80) == 0)
- {
- return ret;
- }
- }
-
- // Still haven't seen a byte with the high bit unset? Dodgy data.
- throw new IOException("Invalid 7-bit encoded integer in stream.");
- }
-
- ///
- /// Reads a 7-bit encoded integer from the stream. This is stored with the most significant
- /// information first, with 7 bits of information per byte of value, and the top
- /// bit as a continuation flag. This method is not affected by the endianness
- /// of the bit converter.
- ///
- /// The 7-bit encoded integer read from the stream.
- public int ReadBigEndian7BitEncodedInt()
- {
- this.CheckDisposed();
-
- int ret = 0;
- for (int i = 0; i < 5; i++)
- {
- int b = this.BaseStream.ReadByte();
- if (b == -1)
- {
- throw new EndOfStreamException();
- }
-
- ret = (ret << 7) | (b & 0x7f);
- if ((b & 0x80) == 0)
- {
- return ret;
- }
- }
-
- // Still haven't seen a byte with the high bit unset? Dodgy data.
- throw new IOException("Invalid 7-bit encoded integer in stream.");
- }
-
- ///
- /// Reads a length-prefixed string from the stream, using the encoding for this reader.
- /// A 7-bit encoded integer is first read, which specifies the number of bytes
- /// to read from the stream. These bytes are then converted into a string with
- /// the encoding for this reader.
- ///
- /// The string read from the stream.
- public string ReadString()
- {
- int bytesToRead = this.Read7BitEncodedInt();
-
- byte[] data = new byte[bytesToRead];
- this.ReadInternal(data, bytesToRead);
- return this.Encoding.GetString(data, 0, data.Length);
- }
-
- ///
- /// Disposes of the underlying stream.
- ///
- public void Dispose()
- {
- if (!this.disposed)
- {
- this.disposed = true;
- ((IDisposable)this.BaseStream).Dispose();
- }
- }
-
- ///
- /// Checks whether or not the reader has been disposed, throwing an exception if so.
- ///
- private void CheckDisposed()
- {
- if (this.disposed)
- {
- throw new ObjectDisposedException("EndianBinaryReader");
- }
- }
-
- ///
- /// Reads the given number of bytes from the stream, throwing an exception
- /// if they can't all be read.
- ///
- /// Buffer to read into
- /// Number of bytes to read
- private void ReadInternal(byte[] data, int size)
- {
- this.CheckDisposed();
- int index = 0;
- while (index < size)
- {
- int read = this.BaseStream.Read(data, index, size - index);
- if (read == 0)
- {
- throw new EndOfStreamException
- (
- string.Format(
- "End of stream reached with {0} byte{1} left to read.",
- size - index,
- size - index == 1 ? "s" : string.Empty));
- }
-
- index += read;
- }
- }
-
- ///
- /// Reads the given number of bytes from the stream if possible, returning
- /// the number of bytes actually read, which may be less than requested if
- /// (and only if) the end of the stream is reached.
- ///
- /// Buffer to read into
- /// Number of bytes to read
- /// Number of bytes actually read
- private int TryReadInternal(byte[] data, int size)
- {
- this.CheckDisposed();
- int index = 0;
- while (index < size)
- {
- int read = this.BaseStream.Read(data, index, size - index);
- if (read == 0)
- {
- return index;
- }
-
- index += read;
- }
-
- return index;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/IO/EndianBinaryWriter.cs b/src/ImageProcessorCore - Copy/IO/EndianBinaryWriter.cs
deleted file mode 100644
index 0f37b9a13d..0000000000
--- a/src/ImageProcessorCore - Copy/IO/EndianBinaryWriter.cs
+++ /dev/null
@@ -1,385 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.IO
-{
- using System;
- using System.IO;
- using System.Text;
-
- ///
- /// Equivalent of , but with either endianness, depending on
- /// the it is constructed with.
- ///
- internal class EndianBinaryWriter : IDisposable
- {
- ///
- /// Buffer used for temporary storage during conversion from primitives
- ///
- private readonly byte[] buffer = new byte[16];
-
- ///
- /// Buffer used for Write(char)
- ///
- private readonly char[] charBuffer = new char[1];
-
- ///
- /// Whether or not this writer has been disposed yet.
- ///
- private bool disposed;
-
- ///
- /// Initializes a new instance of the class
- /// with the given bit converter, writing to the given stream, using UTF-8 encoding.
- ///
- /// Converter to use when writing data
- /// Stream to write data to
- public EndianBinaryWriter(EndianBitConverter bitConverter, Stream stream)
- : this(bitConverter, stream, Encoding.UTF8)
- {
- }
-
- ///
- /// Initializes a new instance of the class
- /// with the given bit converter, writing to the given stream, using the given encoding.
- ///
- /// Converter to use when writing data
- /// Stream to write data to
- ///
- /// Encoding to use when writing character data
- ///
- public EndianBinaryWriter(EndianBitConverter bitConverter, Stream stream, Encoding encoding)
- {
- // TODO: Use Guard
- if (bitConverter == null)
- {
- throw new ArgumentNullException("bitConverter");
- }
-
- if (stream == null)
- {
- throw new ArgumentNullException("stream");
- }
-
- if (encoding == null)
- {
- throw new ArgumentNullException("encoding");
- }
-
- if (!stream.CanWrite)
- {
- throw new ArgumentException("Stream isn't writable", "stream");
- }
-
- this.BaseStream = stream;
- this.BitConverter = bitConverter;
- this.Encoding = encoding;
- }
-
- ///
- /// Gets the bit converter used to write values to the stream
- ///
- public EndianBitConverter BitConverter { get; }
-
- ///
- /// Gets the encoding used to write strings
- ///
- public Encoding Encoding { get; }
-
- ///
- /// Gets the underlying stream of the EndianBinaryWriter.
- ///
- public Stream BaseStream { get; }
-
- ///
- /// Closes the writer, including the underlying stream.
- ///
- public void Close()
- {
- this.Dispose();
- }
-
- ///
- /// Flushes the underlying stream.
- ///
- public void Flush()
- {
- this.CheckDisposed();
- this.BaseStream.Flush();
- }
-
- ///
- /// Seeks within the stream.
- ///
- /// Offset to seek to.
- /// Origin of seek operation.
- public void Seek(int offset, SeekOrigin origin)
- {
- this.CheckDisposed();
- this.BaseStream.Seek(offset, origin);
- }
-
- ///
- /// Writes a boolean value to the stream. 1 byte is written.
- ///
- /// The value to write
- public void Write(bool value)
- {
- this.BitConverter.CopyBytes(value, this.buffer, 0);
- this.WriteInternal(this.buffer, 1);
- }
-
- ///
- /// Writes a 16-bit signed integer to the stream, using the bit converter
- /// for this writer. 2 bytes are written.
- ///
- /// The value to write
- public void Write(short value)
- {
- this.BitConverter.CopyBytes(value, this.buffer, 0);
- this.WriteInternal(this.buffer, 2);
- }
-
- ///
- /// Writes a 32-bit signed integer to the stream, using the bit converter
- /// for this writer. 4 bytes are written.
- ///
- /// The value to write
- public void Write(int value)
- {
- this.BitConverter.CopyBytes(value, this.buffer, 0);
- this.WriteInternal(this.buffer, 4);
- }
-
- ///
- /// Writes a 64-bit signed integer to the stream, using the bit converter
- /// for this writer. 8 bytes are written.
- ///
- /// The value to write
- public void Write(long value)
- {
- this.BitConverter.CopyBytes(value, this.buffer, 0);
- this.WriteInternal(this.buffer, 8);
- }
-
- ///
- /// Writes a 16-bit unsigned integer to the stream, using the bit converter
- /// for this writer. 2 bytes are written.
- ///
- /// The value to write
- public void Write(ushort value)
- {
- this.BitConverter.CopyBytes(value, this.buffer, 0);
- this.WriteInternal(this.buffer, 2);
- }
-
- ///
- /// Writes a 32-bit unsigned integer to the stream, using the bit converter
- /// for this writer. 4 bytes are written.
- ///
- /// The value to write
- public void Write(uint value)
- {
- this.BitConverter.CopyBytes(value, this.buffer, 0);
- this.WriteInternal(this.buffer, 4);
- }
-
- ///
- /// Writes a 64-bit unsigned integer to the stream, using the bit converter
- /// for this writer. 8 bytes are written.
- ///
- /// The value to write
- public void Write(ulong value)
- {
- this.BitConverter.CopyBytes(value, this.buffer, 0);
- this.WriteInternal(this.buffer, 8);
- }
-
- ///
- /// Writes a single-precision floating-point value to the stream, using the bit converter
- /// for this writer. 4 bytes are written.
- ///
- /// The value to write
- public void Write(float value)
- {
- this.BitConverter.CopyBytes(value, this.buffer, 0);
- this.WriteInternal(this.buffer, 4);
- }
-
- ///
- /// Writes a double-precision floating-point value to the stream, using the bit converter
- /// for this writer. 8 bytes are written.
- ///
- /// The value to write
- public void Write(double value)
- {
- this.BitConverter.CopyBytes(value, this.buffer, 0);
- this.WriteInternal(this.buffer, 8);
- }
-
- ///
- /// Writes a decimal value to the stream, using the bit converter for this writer.
- /// 16 bytes are written.
- ///
- /// The value to write
- public void Write(decimal value)
- {
- this.BitConverter.CopyBytes(value, this.buffer, 0);
- this.WriteInternal(this.buffer, 16);
- }
-
- ///
- /// Writes a signed byte to the stream.
- ///
- /// The value to write
- public void Write(byte value)
- {
- this.buffer[0] = value;
- this.WriteInternal(this.buffer, 1);
- }
-
- ///
- /// Writes an unsigned byte to the stream.
- ///
- /// The value to write
- public void Write(sbyte value)
- {
- this.buffer[0] = unchecked((byte)value);
- this.WriteInternal(this.buffer, 1);
- }
-
- ///
- /// Writes an array of bytes to the stream.
- ///
- /// The values to write
- public void Write(byte[] value)
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value));
- }
-
- this.WriteInternal(value, value.Length);
- }
-
- ///
- /// Writes a portion of an array of bytes to the stream.
- ///
- /// An array containing the bytes to write
- /// The index of the first byte to write within the array
- /// The number of bytes to write
- public void Write(byte[] value, int offset, int count)
- {
- this.CheckDisposed();
- this.BaseStream.Write(value, offset, count);
- }
-
- ///
- /// Writes a single character to the stream, using the encoding for this writer.
- ///
- /// The value to write
- public void Write(char value)
- {
- this.charBuffer[0] = value;
- this.Write(this.charBuffer);
- }
-
- ///
- /// Writes an array of characters to the stream, using the encoding for this writer.
- ///
- /// An array containing the characters to write
- public void Write(char[] value)
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value));
- }
-
- this.CheckDisposed();
- byte[] data = this.Encoding.GetBytes(value, 0, value.Length);
- this.WriteInternal(data, data.Length);
- }
-
- ///
- /// Writes a string to the stream, using the encoding for this writer.
- ///
- /// The value to write. Must not be null.
- /// value is null
- public void Write(string value)
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value));
- }
-
- this.CheckDisposed();
- byte[] data = this.Encoding.GetBytes(value);
- this.Write7BitEncodedInt(data.Length);
- this.WriteInternal(data, data.Length);
- }
-
- ///
- /// Writes a 7-bit encoded integer from the stream. This is stored with the least significant
- /// information first, with 7 bits of information per byte of value, and the top
- /// bit as a continuation flag.
- ///
- /// The 7-bit encoded integer to write to the stream
- public void Write7BitEncodedInt(int value)
- {
- this.CheckDisposed();
- if (value < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(value), "Value must be greater than or equal to 0.");
- }
-
- int index = 0;
- while (value >= 128)
- {
- this.buffer[index++] = (byte)((value & 0x7f) | 0x80);
- value = value >> 7;
- index++;
- }
-
- this.buffer[index++] = (byte)value;
- this.BaseStream.Write(this.buffer, 0, index);
- }
-
- ///
- /// Checks whether or not the writer has been disposed, throwing an exception if so.
- ///
- private void CheckDisposed()
- {
- if (this.disposed)
- {
- throw new ObjectDisposedException("EndianBinaryWriter");
- }
- }
-
- ///
- /// Writes the specified number of bytes from the start of the given byte array,
- /// after checking whether or not the writer has been disposed.
- ///
- /// The array of bytes to write from
- /// The number of bytes to write
- private void WriteInternal(byte[] bytes, int length)
- {
- this.CheckDisposed();
- this.BaseStream.Write(bytes, 0, length);
- }
-
- ///
- /// Disposes of the underlying stream.
- ///
- public void Dispose()
- {
- if (!this.disposed)
- {
- this.Flush();
- this.disposed = true;
- ((IDisposable)this.BaseStream).Dispose();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/IO/EndianBitConverter.cs b/src/ImageProcessorCore - Copy/IO/EndianBitConverter.cs
deleted file mode 100644
index d95527002b..0000000000
--- a/src/ImageProcessorCore - Copy/IO/EndianBitConverter.cs
+++ /dev/null
@@ -1,724 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.IO
-{
- using System;
- using System.Diagnostics.CodeAnalysis;
- using System.Runtime.InteropServices;
-
- ///
- /// Equivalent of , but with either endianness.
- ///
- /// Adapted from Miscellaneous Utility Library
- /// This product includes software developed by Jon Skeet and Marc Gravell. Contact , or see
- /// .
- ///
- ///
- [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1201:ElementsMustAppearInTheCorrectOrder", Justification = "Reviewed. Suppression is OK here. Better readability.")]
- [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "Reviewed. Suppression is OK here. Better readability.")]
- [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1204:StaticElementsMustAppearBeforeInstanceElements", Justification = "Reviewed. Suppression is OK here. Better readability.")]
- internal abstract class EndianBitConverter
- {
- #region Endianness of this converter
- ///
- /// Indicates the byte order ("endianness") in which data is converted using this class.
- ///
- ///
- /// Different computer architectures store data using different byte orders. "Big-endian"
- /// means the most significant byte is on the left end of a word. "Little-endian" means the
- /// most significant byte is on the right end of a word.
- ///
- /// true if this converter is little-endian, false otherwise.
- public abstract bool IsLittleEndian();
-
- ///
- /// Gets the byte order ("endianness") in which data is converted using this class.
- ///
- public abstract Endianness Endianness { get; }
- #endregion
-
- #region Factory properties
- ///
- /// The little-endian bit converter.
- ///
- private static readonly LittleEndianBitConverter LittleConverter = new LittleEndianBitConverter();
-
- ///
- /// Gets a little-endian bit converter instance. The same instance is
- /// always returned.
- ///
- public static LittleEndianBitConverter Little => LittleConverter;
-
- ///
- /// The big-endian bit converter.
- ///
- private static readonly BigEndianBitConverter BigConverter = new BigEndianBitConverter();
-
- ///
- /// Gets a big-endian bit converter instance. The same instance is
- /// always returned.
- ///
- public static BigEndianBitConverter Big => BigConverter;
- #endregion
-
- #region Double/primitive conversions
- ///
- /// Converts the specified double-precision floating point number to a
- /// 64-bit signed integer. Note: the endianness of this converter does not
- /// affect the returned value.
- ///
- /// The number to convert.
- /// A 64-bit signed integer whose value is equivalent to value.
- public long DoubleToInt64Bits(double value)
- {
- return BitConverter.DoubleToInt64Bits(value);
- }
-
- ///
- /// Converts the specified 64-bit signed integer to a double-precision
- /// floating point number. Note: the endianness of this converter does not
- /// affect the returned value.
- ///
- /// The number to convert.
- /// A double-precision floating point number whose value is equivalent to value.
- public double Int64BitsToDouble(long value)
- {
- return BitConverter.Int64BitsToDouble(value);
- }
-
- ///
- /// Converts the specified single-precision floating point number to a
- /// 32-bit signed integer. Note: the endianness of this converter does not
- /// affect the returned value.
- ///
- /// The number to convert.
- /// A 32-bit signed integer whose value is equivalent to value.
- public int SingleToInt32Bits(float value)
- {
- return new Int32SingleUnion(value).AsInt32;
- }
-
- ///
- /// Converts the specified 32-bit signed integer to a single-precision floating point
- /// number. Note: the endianness of this converter does not
- /// affect the returned value.
- ///
- /// The number to convert.
- /// A single-precision floating point number whose value is equivalent to value.
- public float Int32BitsToSingle(int value)
- {
- return new Int32SingleUnion(value).AsSingle;
- }
- #endregion
-
- #region To(PrimitiveType) conversions
- ///
- /// Returns a Boolean value converted from one byte at a specified position in a byte array.
- ///
- /// An array of bytes.
- /// The starting position within value.
- /// true if the byte at startIndex in value is nonzero; otherwise, false.
- public bool ToBoolean(byte[] value, int startIndex)
- {
- CheckByteArgument(value, startIndex, 1);
- return BitConverter.ToBoolean(value, startIndex);
- }
-
- ///
- /// Returns a Unicode character converted from two bytes at a specified position in a byte array.
- ///
- /// An array of bytes.
- /// The starting position within value.
- /// A character formed by two bytes beginning at startIndex.
- public char ToChar(byte[] value, int startIndex)
- {
- return unchecked((char)this.CheckedFromBytes(value, startIndex, 2));
- }
-
- ///
- /// Returns a double-precision floating point number converted from eight bytes
- /// at a specified position in a byte array.
- ///
- /// An array of bytes.
- /// The starting position within value.
- /// A double precision floating point number formed by eight bytes beginning at startIndex.
- public double ToDouble(byte[] value, int startIndex)
- {
- return this.Int64BitsToDouble(this.ToInt64(value, startIndex));
- }
-
- ///
- /// Returns a single-precision floating point number converted from four bytes
- /// at a specified position in a byte array.
- ///
- /// An array of bytes.
- /// The starting position within value.
- /// A single precision floating point number formed by four bytes beginning at startIndex.
- public float ToSingle(byte[] value, int startIndex)
- {
- return this.Int32BitsToSingle(this.ToInt32(value, startIndex));
- }
-
- ///
- /// Returns a 16-bit signed integer converted from two bytes at a specified position in a byte array.
- ///
- /// An array of bytes.
- /// The starting position within value.
- /// A 16-bit signed integer formed by two bytes beginning at startIndex.
- public short ToInt16(byte[] value, int startIndex)
- {
- return unchecked((short)this.CheckedFromBytes(value, startIndex, 2));
- }
-
- ///
- /// Returns a 32-bit signed integer converted from four bytes at a specified position in a byte array.
- ///
- /// An array of bytes.
- /// The starting position within value.
- /// A 32-bit signed integer formed by four bytes beginning at startIndex.
- public int ToInt32(byte[] value, int startIndex)
- {
- return unchecked((int)this.CheckedFromBytes(value, startIndex, 4));
- }
-
- ///
- /// Returns a 64-bit signed integer converted from eight bytes at a specified position in a byte array.
- ///
- /// An array of bytes.
- /// The starting position within value.
- /// A 64-bit signed integer formed by eight bytes beginning at startIndex.
- public long ToInt64(byte[] value, int startIndex)
- {
- return this.CheckedFromBytes(value, startIndex, 8);
- }
-
- ///
- /// Returns a 16-bit unsigned integer converted from two bytes at a specified position in a byte array.
- ///
- /// An array of bytes.
- /// The starting position within value.
- /// A 16-bit unsigned integer formed by two bytes beginning at startIndex.
- public ushort ToUInt16(byte[] value, int startIndex)
- {
- return unchecked((ushort)this.CheckedFromBytes(value, startIndex, 2));
- }
-
- ///
- /// Returns a 32-bit unsigned integer converted from four bytes at a specified position in a byte array.
- ///
- /// An array of bytes.
- /// The starting position within value.
- /// A 32-bit unsigned integer formed by four bytes beginning at startIndex.
- public uint ToUInt32(byte[] value, int startIndex)
- {
- return unchecked((uint)this.CheckedFromBytes(value, startIndex, 4));
- }
-
- ///
- /// Returns a 64-bit unsigned integer converted from eight bytes at a specified position in a byte array.
- ///
- /// An array of bytes.
- /// The starting position within value.
- /// A 64-bit unsigned integer formed by eight bytes beginning at startIndex.
- public ulong ToUInt64(byte[] value, int startIndex)
- {
- return unchecked((ulong)this.CheckedFromBytes(value, startIndex, 8));
- }
-
- ///
- /// Convert the given number of bytes from the given array, from the given start
- /// position, into a long, using the bytes as the least significant part of the long.
- /// By the time this is called, the arguments have been checked for validity.
- ///
- /// The bytes to convert
- /// The index of the first byte to convert
- /// The number of bytes to use in the conversion
- /// The converted number
- protected internal abstract long FromBytes(byte[] value, int startIndex, int bytesToConvert);
-
- ///
- /// Checks the given argument for validity.
- ///
- /// The byte array passed in
- /// The start index passed in
- /// The number of bytes required
- /// value is a null reference
- ///
- /// startIndex is less than zero or greater than the length of value minus bytesRequired.
- ///
- [SuppressMessage("ReSharper", "UnusedParameter.Local", Justification = "Keeps code DRY")]
- private static void CheckByteArgument(byte[] value, int startIndex, int bytesRequired)
- {
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value));
- }
-
- if (startIndex < 0 || startIndex > value.Length - bytesRequired)
- {
- throw new ArgumentOutOfRangeException(nameof(startIndex));
- }
- }
-
- ///
- /// Checks the arguments for validity before calling FromBytes
- /// (which can therefore assume the arguments are valid).
- ///
- /// The bytes to convert after checking
- /// The index of the first byte to convert
- /// The number of bytes to convert
- /// The
- private long CheckedFromBytes(byte[] value, int startIndex, int bytesToConvert)
- {
- CheckByteArgument(value, startIndex, bytesToConvert);
- return this.FromBytes(value, startIndex, bytesToConvert);
- }
- #endregion
-
- #region ToString conversions
- ///
- /// Returns a String converted from the elements of a byte array.
- ///
- /// An array of bytes.
- /// All the elements of value are converted.
- ///
- /// A String of hexadecimal pairs separated by hyphens, where each pair
- /// represents the corresponding element in value; for example, "7F-2C-4A".
- ///
- public static string ToString(byte[] value)
- {
- return BitConverter.ToString(value);
- }
-
- ///
- /// Returns a String converted from the elements of a byte array starting at a specified array position.
- ///
- /// An array of bytes.
- /// The starting position within value.
- /// The elements from array position startIndex to the end of the array are converted.
- ///
- /// A String of hexadecimal pairs separated by hyphens, where each pair
- /// represents the corresponding element in value; for example, "7F-2C-4A".
- ///
- public static string ToString(byte[] value, int startIndex)
- {
- return BitConverter.ToString(value, startIndex);
- }
-
- ///
- /// Returns a String converted from a specified number of bytes at a specified position in a byte array.
- ///
- /// An array of bytes.
- /// The starting position within value.
- /// The number of bytes to convert.
- /// The length elements from array position startIndex are converted.
- ///
- /// A String of hexadecimal pairs separated by hyphens, where each pair
- /// represents the corresponding element in value; for example, "7F-2C-4A".
- ///
- public static string ToString(byte[] value, int startIndex, int length)
- {
- return BitConverter.ToString(value, startIndex, length);
- }
- #endregion
-
- #region Decimal conversions
- ///
- /// Returns a decimal value converted from sixteen bytes
- /// at a specified position in a byte array.
- ///
- /// An array of bytes.
- /// The starting position within value.
- /// A decimal formed by sixteen bytes beginning at startIndex.
- public decimal ToDecimal(byte[] value, int startIndex)
- {
- // HACK: This always assumes four parts, each in their own endianness,
- // starting with the first part at the start of the byte array.
- // On the other hand, there's no real format specified...
- int[] parts = new int[4];
- for (int i = 0; i < 4; i++)
- {
- parts[i] = this.ToInt32(value, startIndex + (i * 4));
- }
-
- return new decimal(parts);
- }
-
- ///
- /// Returns the specified decimal value as an array of bytes.
- ///
- /// The number to convert.
- /// An array of bytes with length 16.
- public byte[] GetBytes(decimal value)
- {
- byte[] bytes = new byte[16];
- int[] parts = decimal.GetBits(value);
- for (int i = 0; i < 4; i++)
- {
- this.CopyBytesImpl(parts[i], 4, bytes, i * 4);
- }
-
- return bytes;
- }
-
- ///
- /// Copies the specified decimal value into the specified byte array,
- /// beginning at the specified index.
- ///
- /// A character to convert.
- /// The byte array to copy the bytes into
- /// The first index into the array to copy the bytes into
- public void CopyBytes(decimal value, byte[] buffer, int index)
- {
- int[] parts = decimal.GetBits(value);
- for (int i = 0; i < 4; i++)
- {
- this.CopyBytesImpl(parts[i], 4, buffer, (i * 4) + index);
- }
- }
- #endregion
-
- #region GetBytes conversions
- ///
- /// Returns an array with the given number of bytes formed
- /// from the least significant bytes of the specified value.
- /// This is used to implement the other GetBytes methods.
- ///
- /// The value to get bytes for
- /// The number of significant bytes to return
- ///
- /// The .
- ///
- private byte[] GetBytes(long value, int bytes)
- {
- byte[] buffer = new byte[bytes];
- this.CopyBytes(value, bytes, buffer, 0);
- return buffer;
- }
-
- ///
- /// Returns the specified Boolean value as an array of bytes.
- ///
- /// A Boolean value.
- /// An array of bytes with length 1.
- ///
- /// The .
- ///
- public byte[] GetBytes(bool value)
- {
- return BitConverter.GetBytes(value);
- }
-
- ///
- /// Returns the specified Unicode character value as an array of bytes.
- ///
- /// A character to convert.
- /// An array of bytes with length 2.
- ///
- /// The .
- ///
- public byte[] GetBytes(char value)
- {
- return this.GetBytes(value, 2);
- }
-
- ///
- /// Returns the specified double-precision floating point value as an array of bytes.
- ///
- /// The number to convert.
- /// An array of bytes with length 8.
- public byte[] GetBytes(double value)
- {
- return this.GetBytes(this.DoubleToInt64Bits(value), 8);
- }
-
- ///
- /// Returns the specified 16-bit signed integer value as an array of bytes.
- ///
- /// The number to convert.
- /// An array of bytes with length 2.
- public byte[] GetBytes(short value)
- {
- return this.GetBytes(value, 2);
- }
-
- ///
- /// Returns the specified 32-bit signed integer value as an array of bytes.
- ///
- /// The number to convert.
- /// An array of bytes with length 4.
- public byte[] GetBytes(int value)
- {
- return this.GetBytes(value, 4);
- }
-
- ///
- /// Returns the specified 64-bit signed integer value as an array of bytes.
- ///
- /// The number to convert.
- /// An array of bytes with length 8.
- public byte[] GetBytes(long value)
- {
- return this.GetBytes(value, 8);
- }
-
- ///
- /// Returns the specified single-precision floating point value as an array of bytes.
- ///
- /// The number to convert.
- /// An array of bytes with length 4.
- public byte[] GetBytes(float value)
- {
- return this.GetBytes(this.SingleToInt32Bits(value), 4);
- }
-
- ///
- /// Returns the specified 16-bit unsigned integer value as an array of bytes.
- ///
- /// The number to convert.
- /// An array of bytes with length 2.
- public byte[] GetBytes(ushort value)
- {
- return this.GetBytes(value, 2);
- }
-
- ///
- /// Returns the specified 32-bit unsigned integer value as an array of bytes.
- ///
- /// The number to convert.
- /// An array of bytes with length 4.
- public byte[] GetBytes(uint value)
- {
- return this.GetBytes(value, 4);
- }
-
- ///
- /// Returns the specified 64-bit unsigned integer value as an array of bytes.
- ///
- /// The number to convert.
- /// An array of bytes with length 8.
- public byte[] GetBytes(ulong value)
- {
- return this.GetBytes(unchecked((long)value), 8);
- }
-
- #endregion
-
- #region CopyBytes conversions
- ///
- /// Copies the given number of bytes from the least-specific
- /// end of the specified value into the specified byte array, beginning
- /// at the specified index.
- /// This is used to implement the other CopyBytes methods.
- ///
- /// The value to copy bytes for
- /// The number of significant bytes to copy
- /// The byte array to copy the bytes into
- /// The first index into the array to copy the bytes into
- private void CopyBytes(long value, int bytes, byte[] buffer, int index)
- {
- if (buffer == null)
- {
- throw new ArgumentNullException(nameof(buffer), "Byte array must not be null");
- }
-
- if (buffer.Length < index + bytes)
- {
- throw new ArgumentOutOfRangeException(nameof(buffer), "Buffer not big enough for value");
- }
-
- this.CopyBytesImpl(value, bytes, buffer, index);
- }
-
- ///
- /// Copies the given number of bytes from the least-specific
- /// end of the specified value into the specified byte array, beginning
- /// at the specified index.
- /// This must be implemented in concrete derived classes, but the implementation
- /// may assume that the value will fit into the buffer.
- ///
- /// The value to copy bytes for
- /// The number of significant bytes to copy
- /// The byte array to copy the bytes into
- /// The first index into the array to copy the bytes into
- protected internal abstract void CopyBytesImpl(long value, int bytes, byte[] buffer, int index);
-
- ///
- /// Copies the specified Boolean value into the specified byte array,
- /// beginning at the specified index.
- ///
- /// A Boolean value.
- /// The byte array to copy the bytes into
- /// The first index into the array to copy the bytes into
- public void CopyBytes(bool value, byte[] buffer, int index)
- {
- this.CopyBytes(value ? 1 : 0, 1, buffer, index);
- }
-
- ///
- /// Copies the specified Unicode character value into the specified byte array,
- /// beginning at the specified index.
- ///
- /// A character to convert.
- /// The byte array to copy the bytes into
- /// The first index into the array to copy the bytes into
- public void CopyBytes(char value, byte[] buffer, int index)
- {
- this.CopyBytes(value, 2, buffer, index);
- }
-
- ///
- /// Copies the specified double-precision floating point value into the specified byte array,
- /// beginning at the specified index.
- ///
- /// The number to convert.
- /// The byte array to copy the bytes into
- /// The first index into the array to copy the bytes into
- public void CopyBytes(double value, byte[] buffer, int index)
- {
- this.CopyBytes(this.DoubleToInt64Bits(value), 8, buffer, index);
- }
-
- ///
- /// Copies the specified 16-bit signed integer value into the specified byte array,
- /// beginning at the specified index.
- ///
- /// The number to convert.
- /// The byte array to copy the bytes into
- /// The first index into the array to copy the bytes into
- public void CopyBytes(short value, byte[] buffer, int index)
- {
- this.CopyBytes(value, 2, buffer, index);
- }
-
- ///
- /// Copies the specified 32-bit signed integer value into the specified byte array,
- /// beginning at the specified index.
- ///
- /// The number to convert.
- /// The byte array to copy the bytes into
- /// The first index into the array to copy the bytes into
- public void CopyBytes(int value, byte[] buffer, int index)
- {
- this.CopyBytes(value, 4, buffer, index);
- }
-
- ///
- /// Copies the specified 64-bit signed integer value into the specified byte array,
- /// beginning at the specified index.
- ///
- /// The number to convert.
- /// The byte array to copy the bytes into
- /// The first index into the array to copy the bytes into
- public void CopyBytes(long value, byte[] buffer, int index)
- {
- this.CopyBytes(value, 8, buffer, index);
- }
-
- ///
- /// Copies the specified single-precision floating point value into the specified byte array,
- /// beginning at the specified index.
- ///
- /// The number to convert.
- /// The byte array to copy the bytes into
- /// The first index into the array to copy the bytes into
- public void CopyBytes(float value, byte[] buffer, int index)
- {
- this.CopyBytes(this.SingleToInt32Bits(value), 4, buffer, index);
- }
-
- ///
- /// Copies the specified 16-bit unsigned integer value into the specified byte array,
- /// beginning at the specified index.
- ///
- /// The number to convert.
- /// The byte array to copy the bytes into
- /// The first index into the array to copy the bytes into
- public void CopyBytes(ushort value, byte[] buffer, int index)
- {
- this.CopyBytes(value, 2, buffer, index);
- }
-
- ///
- /// Copies the specified 32-bit unsigned integer value into the specified byte array,
- /// beginning at the specified index.
- ///
- /// The number to convert.
- /// The byte array to copy the bytes into
- /// The first index into the array to copy the bytes into
- public void CopyBytes(uint value, byte[] buffer, int index)
- {
- this.CopyBytes(value, 4, buffer, index);
- }
-
- ///
- /// Copies the specified 64-bit unsigned integer value into the specified byte array,
- /// beginning at the specified index.
- ///
- /// The number to convert.
- /// The byte array to copy the bytes into
- /// The first index into the array to copy the bytes into
- public void CopyBytes(ulong value, byte[] buffer, int index)
- {
- this.CopyBytes(unchecked((long)value), 8, buffer, index);
- }
-
- #endregion
-
- #region Private struct used for Single/Int32 conversions
- ///
- /// Union used solely for the equivalent of DoubleToInt64Bits and vice versa.
- ///
- [StructLayout(LayoutKind.Explicit)]
- private struct Int32SingleUnion
- {
- ///
- /// Int32 version of the value.
- ///
- [FieldOffset(0)]
- private readonly int i;
-
- ///
- /// Single version of the value.
- ///
- [FieldOffset(0)]
- private readonly float f;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The integer value of the new instance.
- internal Int32SingleUnion(int i)
- {
- this.f = 0; // Just to keep the compiler happy
- this.i = i;
- }
-
- ///
- /// Initializes a new instance of the struct.
- ///
- ///
- /// The floating point value of the new instance.
- ///
- internal Int32SingleUnion(float f)
- {
- this.i = 0; // Just to keep the compiler happy
- this.f = f;
- }
-
- ///
- /// Gets the value of the instance as an integer.
- ///
- internal int AsInt32 => this.i;
-
- ///
- /// Gets the value of the instance as a floating point number.
- ///
- internal float AsSingle => this.f;
- }
- #endregion
- }
-}
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/IO/Endianness.cs b/src/ImageProcessorCore - Copy/IO/Endianness.cs
deleted file mode 100644
index e8e4ef4c2d..0000000000
--- a/src/ImageProcessorCore - Copy/IO/Endianness.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.IO
-{
- ///
- /// Endianness of a converter
- ///
- internal enum Endianness
- {
- ///
- /// Little endian - least significant byte first
- ///
- LittleEndian,
-
- ///
- /// Big endian - most significant byte first
- ///
- BigEndian
- }
-}
diff --git a/src/ImageProcessorCore - Copy/IO/LittleEndianBitConverter.cs b/src/ImageProcessorCore - Copy/IO/LittleEndianBitConverter.cs
deleted file mode 100644
index 70e65d9091..0000000000
--- a/src/ImageProcessorCore - Copy/IO/LittleEndianBitConverter.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.IO
-{
- ///
- /// Implementation of EndianBitConverter which converts to/from little-endian
- /// byte arrays.
- ///
- /// Adapted from Miscellaneous Utility Library
- /// This product includes software developed by Jon Skeet and Marc Gravell. Contact , or see
- /// .
- ///
- ///
- internal sealed class LittleEndianBitConverter : EndianBitConverter
- {
- ///
- public override Endianness Endianness => Endianness.LittleEndian;
-
- ///
- public override bool IsLittleEndian() => true;
-
- ///
- protected internal override void CopyBytesImpl(long value, int bytes, byte[] buffer, int index)
- {
- for (int i = 0; i < bytes; i++)
- {
- buffer[i + index] = unchecked((byte)(value & 0xff));
- value = value >> 8;
- }
- }
-
- ///
- protected internal override long FromBytes(byte[] buffer, int startIndex, int bytesToConvert)
- {
- long ret = 0;
- for (int i = 0; i < bytesToConvert; i++)
- {
- ret = unchecked((ret << 8) | buffer[startIndex + bytesToConvert - 1 - i]);
- }
-
- return ret;
- }
- }
-}
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/Image.cs b/src/ImageProcessorCore - Copy/Image.cs
deleted file mode 100644
index c8dc861d6a..0000000000
--- a/src/ImageProcessorCore - Copy/Image.cs
+++ /dev/null
@@ -1,291 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System.IO;
- using System.Text;
-
- using System;
- using System.Collections.Generic;
- using System.Linq;
-
- using Formats;
-
- ///
- /// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes.
- ///
- ///
- /// The packed vector containing pixel information.
- ///
- public class Image : ImageBase
- where TPackedVector : IPackedVector
- {
- ///
- /// The default horizontal resolution value (dots per inch) in x direction.
- /// The default value is 96 dots per inch.
- ///
- public const double DefaultHorizontalResolution = 96;
-
- ///
- /// The default vertical resolution value (dots per inch) in y direction.
- /// The default value is 96 dots per inch.
- ///
- public const double DefaultVerticalResolution = 96;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public Image()
- {
- this.CurrentImageFormat = Bootstrapper.Instance.ImageFormats.First(f => f.GetType() == typeof(PngFormat));
- }
-
- ///
- /// Initializes a new instance of the class
- /// with the height and the width of the image.
- ///
- /// The width of the image in pixels.
- /// The height of the image in pixels.
- public Image(int width, int height)
- : base(width, height)
- {
- this.CurrentImageFormat = Bootstrapper.Instance.ImageFormats.First(f => f.GetType() == typeof(PngFormat));
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The stream containing image information.
- ///
- /// Thrown if the is null.
- public Image(Stream stream)
- {
- Guard.NotNull(stream, nameof(stream));
- this.Load(stream);
- }
-
- ///
- /// Initializes a new instance of the class
- /// by making a copy from another image.
- ///
- /// The other image, where the clone should be made from.
- /// is null.
- public Image(Image other)
- {
- foreach (ImageFrame frame in other.Frames)
- {
- if (frame != null)
- {
- this.Frames.Add(new ImageFrame(frame));
- }
- }
-
- this.RepeatCount = other.RepeatCount;
- this.HorizontalResolution = other.HorizontalResolution;
- this.VerticalResolution = other.VerticalResolution;
- this.CurrentImageFormat = other.CurrentImageFormat;
- }
-
- ///
- /// Gets a list of supported image formats.
- ///
- public IReadOnlyCollection Formats { get; } = Bootstrapper.Instance.ImageFormats;
-
- ///
- /// Gets or sets the resolution of the image in x- direction. It is defined as
- /// number of dots per inch and should be an positive value.
- ///
- /// The density of the image in x- direction.
- public double HorizontalResolution { get; set; } = DefaultHorizontalResolution;
-
- ///
- /// Gets or sets the resolution of the image in y- direction. It is defined as
- /// number of dots per inch and should be an positive value.
- ///
- /// The density of the image in y- direction.
- public double VerticalResolution { get; set; } = DefaultVerticalResolution;
-
- ///
- /// Gets the width of the image in inches. It is calculated as the width of the image
- /// in pixels multiplied with the density. When the density is equals or less than zero
- /// the default value is used.
- ///
- /// The width of the image in inches.
- public double InchWidth
- {
- get
- {
- double resolution = this.HorizontalResolution;
-
- if (resolution <= 0)
- {
- resolution = DefaultHorizontalResolution;
- }
-
- return this.Width / resolution;
- }
- }
-
- ///
- /// Gets the height of the image in inches. It is calculated as the height of the image
- /// in pixels multiplied with the density. When the density is equals or less than zero
- /// the default value is used.
- ///
- /// The height of the image in inches.
- public double InchHeight
- {
- get
- {
- double resolution = this.VerticalResolution;
-
- if (resolution <= 0)
- {
- resolution = DefaultVerticalResolution;
- }
-
- return this.Height / resolution;
- }
- }
-
- ///
- /// Gets a value indicating whether this image is animated.
- ///
- ///
- /// True if this image is animated; otherwise, false.
- ///
- public bool IsAnimated => this.Frames.Count > 0;
-
- ///
- /// Gets or sets the number of times any animation is repeated.
- /// 0 means to repeat indefinitely.
- ///
- public ushort RepeatCount { get; set; }
-
- ///
- /// Gets the other frames for the animation.
- ///
- /// The list of frame images.
- public IList> Frames { get; } = new List>();
-
- ///
- /// Gets the list of properties for storing meta information about this image.
- ///
- /// A list of image properties.
- public IList Properties { get; } = new List();
-
- ///
- /// Gets the currently loaded image format.
- ///
- public IImageFormat CurrentImageFormat { get; internal set; }
-
- ///
- public override IPixelAccessor Lock()
- {
- return Bootstrapper.Instance.GetPixelAccessor(this);
- }
-
- ///
- /// Saves the image to the given stream using the currently loaded image format.
- ///
- /// The stream to save the image to.
- /// Thrown if the stream is null.
- public void Save(Stream stream)
- {
- Guard.NotNull(stream, nameof(stream));
- this.CurrentImageFormat.Encoder.Encode(this, stream);
- }
-
- ///
- /// Saves the image to the given stream using the given image format.
- ///
- /// The stream to save the image to.
- /// The format to save the image as.
- /// Thrown if the stream is null.
- public void Save(Stream stream, IImageFormat format)
- {
- Guard.NotNull(stream, nameof(stream));
- format.Encoder.Encode(this, stream);
- }
-
- ///
- /// Saves the image to the given stream using the given image encoder.
- ///
- /// The stream to save the image to.
- /// The encoder to save the image with.
- /// Thrown if the stream is null.
- public void Save(Stream stream, IImageEncoder encoder)
- {
- Guard.NotNull(stream, nameof(stream));
- encoder.Encode(this, stream);
- }
-
- ///
- /// Returns a Base64 encoded string from the given image.
- ///
- /// data:image/gif;base64,R0lGODlhAQABAIABAEdJRgAAACwAAAAAAQABAAACAkQBAA==
- /// The
- public override string ToString()
- {
- using (MemoryStream stream = new MemoryStream())
- {
- this.Save(stream);
- stream.Flush();
- return $"data:{this.CurrentImageFormat.Encoder.MimeType};base64,{Convert.ToBase64String(stream.ToArray())}";
- }
- }
-
- ///
- /// Loads the image from the given stream.
- ///
- /// The stream containing image information.
- ///
- /// Thrown if the stream is not readable nor seekable.
- ///
- private void Load(Stream stream)
- {
- if (!this.Formats.Any()) { return; }
-
- if (!stream.CanRead)
- {
- throw new NotSupportedException("Cannot read from the stream.");
- }
-
- if (!stream.CanSeek)
- {
- throw new NotSupportedException("The stream does not support seeking.");
- }
-
- int maxHeaderSize = this.Formats.Max(x => x.Decoder.HeaderSize);
- if (maxHeaderSize > 0)
- {
- byte[] header = new byte[maxHeaderSize];
-
- stream.Position = 0;
- stream.Read(header, 0, maxHeaderSize);
- stream.Position = 0;
-
- IImageFormat format = this.Formats.FirstOrDefault(x => x.Decoder.IsSupportedFileFormat(header));
- if (format != null)
- {
- format.Decoder.Decode(this, stream);
- this.CurrentImageFormat = format;
- return;
- }
- }
-
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.AppendLine("Image cannot be loaded. Available formats:");
-
- foreach (IImageFormat format in this.Formats)
- {
- stringBuilder.AppendLine("-" + format);
- }
-
- throw new NotSupportedException(stringBuilder.ToString());
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/ImageBase.cs b/src/ImageProcessorCore - Copy/ImageBase.cs
deleted file mode 100644
index 5fa83df4c7..0000000000
--- a/src/ImageProcessorCore - Copy/ImageBase.cs
+++ /dev/null
@@ -1,201 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
-
- ///
- /// The base class of all images. Encapsulates the basic properties and methods required to manipulate images
- /// in different pixel formats.
- ///
- ///
- /// The packed vector pixels format.
- ///
- public abstract class ImageBase : IImageBase
- where TPacked : IPackedVector
- {
- ///
- /// 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 TPacked[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 TPacked[this.Width * this.Height];
- Array.Copy(other.Pixels, this.Pixels, other.Pixels.Length);
- }
-
- ///
- /// Gets or sets the maximum allowable width in pixels.
- ///
- public int MaxWidth { get; set; } = int.MaxValue;
-
- ///
- /// Gets or sets the maximum allowable height in pixels.
- ///
- public int MaxHeight { get; set; } = int.MaxValue;
-
- ///
- /// Gets the pixels as an array of the given packed pixel format.
- ///
- public TPacked[] 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, TPacked[] 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, TPacked[] 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 TPacked[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/src/ImageProcessorCore - Copy/ImageExtensions.cs b/src/ImageProcessorCore - Copy/ImageExtensions.cs
deleted file mode 100644
index ea320aad4d..0000000000
--- a/src/ImageProcessorCore - Copy/ImageExtensions.cs
+++ /dev/null
@@ -1,167 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.IO;
-
- using Formats;
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Saves the image to the given stream with the bmp format.
- ///
- /// The image this method extends.
- /// The stream to save the image to.
- /// Thrown if the stream is null.
- public static void SaveAsBmp(this ImageBase source, Stream stream) => new BmpEncoder().Encode(source, stream);
-
- ///
- /// Saves the image to the given stream with the png format.
- ///
- /// The image this method extends.
- /// The stream to save the image to.
- /// The quality to save the image to representing the number of colors.
- /// Anything equal to 256 and below will cause the encoder to save the image in an indexed format.
- ///
- /// Thrown if the stream is null.
- public static void SaveAsPng(this ImageBase source, Stream stream, int quality = Int32.MaxValue) => new PngEncoder { Quality = quality }.Encode(source, stream);
-
- ///
- /// Saves the image to the given stream with the jpeg format.
- ///
- /// The image this method extends.
- /// The stream to save the image to.
- /// The quality to save the image to. Between 1 and 100.
- /// Thrown if the stream is null.
- public static void SaveAsJpeg(this ImageBase source, Stream stream, int quality = 75) => new JpegEncoder { Quality = quality }.Encode(source, stream);
-
- ///
- /// Saves the image to the given stream with the gif format.
- ///
- /// The image this method extends.
- /// The stream to save the image to.
- /// The quality to save the image to representing the number of colors. Between 1 and 256.
- /// Thrown if the stream is null.
- public static void SaveAsGif(this ImageBase source, Stream stream, int quality = 256) => new GifEncoder { Quality = quality }.Encode(source, stream);
-
- ///
- /// Applies the collection of processors to the image.
- /// This method does not resize the target image.
- ///
- /// The image this method extends.
- /// The processor to apply to the image.
- /// The .
- public static Image Process(this Image source, IImageProcessor processor)
- {
- return Process(source, source.Bounds, processor);
- }
-
- ///
- /// Applies the collection of processors to the image.
- /// This method does not resize the target image.
- ///
- /// The image this method extends.
- ///
- /// The structure that specifies the portion of the image object to draw.
- ///
- /// The processors to apply to the image.
- /// The .
- public static Image Process(this Image source, Rectangle sourceRectangle, IImageProcessor processor)
- {
- return PerformAction(source, true, (sourceImage, targetImage) => processor.Apply(targetImage, sourceImage, sourceRectangle));
- }
-
- ///
- /// Applies the collection of processors to the image.
- ///
- /// This method is not chainable.
- ///
- ///
- /// The source image. Cannot be null.
- /// The target image width.
- /// The target image height.
- /// The processor to apply to the image.
- /// The .
- public static Image Process(this Image source, int width, int height, IImageSampler sampler)
- {
- return Process(source, width, height, source.Bounds, default(Rectangle), sampler);
- }
-
- ///
- /// Applies the collection of processors to the image.
- ///
- /// This method does will resize the target image if the source and target rectangles are different.
- ///
- ///
- /// The source image. Cannot be null.
- /// The target image width.
- /// The target image height.
- ///
- /// The structure that specifies the portion of the image object to draw.
- ///
- ///
- /// The structure that specifies the location and size of the drawn image.
- /// The image is scaled to fit the rectangle.
- ///
- /// 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)
- {
- return PerformAction(source, false, (sourceImage, targetImage) => sampler.Apply(targetImage, sourceImage, width, height, targetRectangle, sourceRectangle));
- }
-
- ///
- /// Performs the given action on the source image.
- ///
- /// The image to perform the action against.
- /// Whether to clone the image.
- /// The to perform against the image.
- /// The .
- /// Thrown if the has been disposed.
- private static Image PerformAction(Image source, bool clone, Action action)
- {
- Image transformedImage = clone
- ? new Image(source)
- : new Image
- {
- // Several properties require copying
- // TODO: Check why we need to set these?
- Quality = source.Quality,
- HorizontalResolution = source.HorizontalResolution,
- VerticalResolution = source.VerticalResolution,
- CurrentImageFormat = source.CurrentImageFormat,
- RepeatCount = source.RepeatCount
- };
-
- action(source, transformedImage);
-
- for (int i = 0; i < source.Frames.Count; i++)
- {
- ImageFrame sourceFrame = source.Frames[i];
- ImageFrame tranformedFrame = clone ? new ImageFrame(sourceFrame) : new ImageFrame { FrameDelay = sourceFrame.FrameDelay };
- action(sourceFrame, tranformedFrame);
-
- if (!clone)
- {
- transformedImage.Frames.Add(tranformedFrame);
- }
- else
- {
- transformedImage.Frames[i] = tranformedFrame;
- }
- }
-
- source = transformedImage;
- return source;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/ImageFrame.cs b/src/ImageProcessorCore - Copy/ImageFrame.cs
deleted file mode 100644
index 479d9dd9b0..0000000000
--- a/src/ImageProcessorCore - Copy/ImageFrame.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// Represents a single frame in a animation.
- ///
- ///
- /// The packed vector containing pixel information.
- ///
- public class ImageFrame : ImageBase
- where TPackedVector : IPackedVector
- {
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The frame to create the frame from.
- ///
- public ImageFrame(ImageFrame frame)
- : base(frame)
- {
- }
-
- ///
- public override IPixelAccessor Lock()
- {
- return Bootstrapper.Instance.GetPixelAccessor(this);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/ImageProcessor.cs b/src/ImageProcessorCore - Copy/ImageProcessor.cs
deleted file mode 100644
index e7057a3f9c..0000000000
--- a/src/ImageProcessorCore - Copy/ImageProcessor.cs
+++ /dev/null
@@ -1,163 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System;
- using System.Threading;
-
- ///
- /// 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 TPackedVector : IPackedVector
- {
- 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 = default(Rectangle), Rectangle sourceRectangle = default(Rectangle))
- where TPackedVector : IPackedVector
- {
- try
- {
- TPackedVector[] pixels = new TPackedVector[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 TPackedVector : IPackedVector
- {
- }
-
- ///
- /// 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 TPackedVector : IPackedVector;
-
- ///
- /// 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 TPackedVector : IPackedVector
- {
- }
-
- ///
- /// 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/src/ImageProcessorCore - Copy/ImageProcessorCore.xproj b/src/ImageProcessorCore - Copy/ImageProcessorCore.xproj
deleted file mode 100644
index ffe5b1cea0..0000000000
--- a/src/ImageProcessorCore - Copy/ImageProcessorCore.xproj
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
- 14.0
- $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
-
-
-
- 2aa31a1f-142c-43f4-8687-09abca4b3a26
- ImageProcessorCore
- .\obj
- .\bin\
- v4.5.1
-
-
- 2.0
-
-
- True
-
-
-
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/ImageProperty.cs b/src/ImageProcessorCore - Copy/ImageProperty.cs
deleted file mode 100644
index 1d8f5bb8ef..0000000000
--- a/src/ImageProcessorCore - Copy/ImageProperty.cs
+++ /dev/null
@@ -1,153 +0,0 @@
-// --------------------------------------------------------------------------------------------------------------------
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-//
-// Stores meta information about a image, like the name of the author,
-// the copyright information, the date, where the image was created
-// or some other information.
-//
-// --------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using System;
-
- ///
- /// Stores meta information about a image, like the name of the author,
- /// the copyright information, the date, where the image was created
- /// or some other information.
- ///
- public struct ImageProperty : IEquatable
- {
- ///
- /// Initializes a new instance of the struct.
- ///
- ///
- /// The name of the property.
- ///
- ///
- /// The value of the property.
- ///
- public ImageProperty(string name, string value)
- {
- this.Name = name;
- this.Value = value;
- }
-
- ///
- /// Gets the name of this indicating which kind of
- /// information this property stores.
- ///
- ///
- /// Typical properties are the author, copyright
- /// information or other meta information.
- ///
- public string Name { get; }
-
- ///
- /// The value of this .
- ///
- public string Value { get; }
-
- ///
- /// Compares two objects. The result specifies whether the values
- /// of the or properties of the two
- /// objects are equal.
- ///
- ///
- /// 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 ==(ImageProperty left, ImageProperty right)
- {
- return left.Equals(right);
- }
-
- ///
- /// Compares two objects. The result specifies whether the values
- /// of the or properties of the two
- /// objects are unequal.
- ///
- ///
- /// The on the left side of the operand.
- ///
- ///
- /// The on the right side of the operand.
- ///
- ///
- /// True if the current left is unequal to the parameter; otherwise, false.
- ///
- public static bool operator !=(ImageProperty left, ImageProperty right)
- {
- return !left.Equals(right);
- }
-
- ///
- /// Indicates whether this instance and a specified object are equal.
- ///
- ///
- /// The object to compare with the current instance.
- ///
- ///
- /// true if and this instance are the same type and represent the
- /// same value; otherwise, false.
- ///
- public override bool Equals(object obj)
- {
- if (!(obj is ImageProperty))
- {
- return false;
- }
-
- ImageProperty other = (ImageProperty)obj;
-
- return other.Name == this.Name && other.Value == this.Value;
- }
-
- ///
- /// Returns the hash code for this instance.
- ///
- ///
- /// A 32-bit signed integer that is the hash code for this instance.
- ///
- public override int GetHashCode()
- {
- unchecked
- {
- int hashCode = this.Name.GetHashCode();
- hashCode = (hashCode * 397) ^ this.Value.GetHashCode();
- return hashCode;
- }
- }
-
- ///
- /// Returns the fully qualified type name of this instance.
- ///
- ///
- /// A containing a fully qualified type name.
- ///
- public override string ToString()
- {
- return $"ImageProperty [ Name={this.Name}, Value={this.Value} ]";
- }
-
- ///
- /// Indicates whether the current object is equal to another object of the same type.
- ///
- ///
- /// True if the current object is equal to the parameter; otherwise, false.
- ///
- /// An object to compare with this object.
- public bool Equals(ImageProperty other)
- {
- return this.Name.Equals(other.Name) && this.Value.Equals(other.Value);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Numerics/Ellipse.cs b/src/ImageProcessorCore - Copy/Numerics/Ellipse.cs
deleted file mode 100644
index 5d87d1247b..0000000000
--- a/src/ImageProcessorCore - Copy/Numerics/Ellipse.cs
+++ /dev/null
@@ -1,174 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.ComponentModel;
- using System.Numerics;
-
- public struct Ellipse : IEquatable
- {
- ///
- /// The center point.
- ///
- private Point center;
-
- ///
- /// Represents a that has X and Y values set to zero.
- ///
- public static readonly Ellipse Empty = default(Ellipse);
-
- public Ellipse(Point center, float radiusX, float radiusY)
- {
- this.center = center;
- this.RadiusX = radiusX;
- this.RadiusY = radiusY;
- }
-
- ///
- /// Gets the x-radius of this .
- ///
- public float RadiusX { get; }
-
- ///
- /// Gets the y-radius of this .
- ///
- public float RadiusY { get; }
-
- ///
- /// Gets a value indicating whether this is empty.
- ///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public bool IsEmpty => this.Equals(Empty);
-
- ///
- /// 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 ==(Ellipse left, Ellipse right)
- {
- return left.Equals(right);
- }
-
- ///
- /// Compares two objects for inequality.
- ///
- ///
- /// The on the left side of the operand.
- ///
- ///
- /// The on the right side of the operand.
- ///
- ///
- /// True if the current left is unequal to the parameter; otherwise, false.
- ///
- public static bool operator !=(Ellipse left, Ellipse right)
- {
- return !left.Equals(right);
- }
-
- ///
- /// Returns the center point of the given
- ///
- /// The ellipse
- ///
- public static Vector2 Center(Ellipse ellipse)
- {
- return new Vector2(ellipse.center.X, ellipse.center.Y);
- }
-
- ///
- /// Determines if the specfied point is contained within the rectangular region defined by
- /// this .
- ///
- /// The x-coordinate of the given point.
- /// The y-coordinate of the given point.
- /// The
- public bool Contains(int x, int y)
- {
- if (this.RadiusX <= 0 || this.RadiusY <= 0)
- {
- return false;
- }
-
- // TODO: SIMD?
- // This is a more general form of the circle equation
- // X^2/a^2 + Y^2/b^2 <= 1
- Point normalized = new Point(x - this.center.X, y - this.center.Y);
- int nX = normalized.X;
- int nY = normalized.Y;
-
- return (double)(nX * nX) / (this.RadiusX * this.RadiusX)
- + (double)(nY * nY) / (this.RadiusY * this.RadiusY)
- <= 1.0;
- }
-
- ///
- public override int GetHashCode()
- {
- return this.GetHashCode(this);
- }
-
- ///
- public override string ToString()
- {
- if (this.IsEmpty)
- {
- return "Ellipse [ Empty ]";
- }
-
- return
- $"Ellipse [ RadiusX={this.RadiusX}, RadiusY={this.RadiusX}, Centre={this.center.X},{this.center.Y} ]";
- }
-
- ///
- public override bool Equals(object obj)
- {
- if (obj is Ellipse)
- {
- return this.Equals((Ellipse)obj);
- }
-
- return false;
- }
-
- ///
- public bool Equals(Ellipse other)
- {
- return this.center.Equals(other.center)
- && this.RadiusX.Equals(other.RadiusX)
- && this.RadiusY.Equals(other.RadiusY);
- }
-
- ///
- /// 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(Ellipse ellipse)
- {
- unchecked
- {
- int hashCode = ellipse.center.GetHashCode();
- hashCode = (hashCode * 397) ^ ellipse.RadiusX.GetHashCode();
- hashCode = (hashCode * 397) ^ ellipse.RadiusY.GetHashCode();
- return hashCode;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Numerics/Point.cs b/src/ImageProcessorCore - Copy/Numerics/Point.cs
deleted file mode 100644
index 818002f9ef..0000000000
--- a/src/ImageProcessorCore - Copy/Numerics/Point.cs
+++ /dev/null
@@ -1,281 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-namespace ImageProcessorCore
-{
- using System;
- using System.ComponentModel;
- using System.Numerics;
-
- ///
- /// Represents an ordered pair of integer x- and y-coordinates that defines a point in
- /// a two-dimensional plane.
- ///
- ///
- /// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
- /// as it avoids the need to create new values for modification operations.
- ///
- public struct Point : IEquatable
- {
- ///
- /// Represents a that has X and Y values set to zero.
- ///
- public static readonly Point Empty = default(Point);
-
- ///
- /// The backing vector for SIMD support.
- ///
- private Vector2 backingVector;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The horizontal position of the point.
- /// The vertical position of the point.
- public Point(int x, int y)
- : this()
- {
- this.backingVector = new Vector2(x, y);
- }
-
- ///
- /// Initializes a new instance of the struct.
- ///
- ///
- /// The vector representing the width and height.
- ///
- public Point(Vector2 vector)
- {
- this.backingVector = new Vector2(vector.X, vector.Y);
- }
-
- ///
- /// The x-coordinate of this .
- ///
- public int X
- {
- get
- {
- return (int)this.backingVector.X;
- }
-
- set
- {
- this.backingVector.X = value;
- }
- }
-
- ///
- /// The y-coordinate of this .
- ///
- public int Y
- {
- get
- {
- return (int)this.backingVector.Y;
- }
-
- set
- {
- this.backingVector.Y = value;
- }
- }
-
- ///
- /// Gets a value indicating whether this is empty.
- ///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public bool IsEmpty => this.Equals(Empty);
-
- ///
- /// Computes the sum of adding two points.
- ///
- /// The point on the left hand of the operand.
- /// The point on the right hand of the operand.
- ///
- /// The
- ///
- public static Point operator +(Point left, Point right)
- {
- return new Point(left.backingVector + right.backingVector);
- }
-
- ///
- /// Computes the difference left by subtracting one point from another.
- ///
- /// The point on the left hand of the operand.
- /// The point on the right hand of the operand.
- ///
- /// The
- ///
- public static Point operator -(Point left, Point right)
- {
- return new Point(left.backingVector - right.backingVector);
- }
-
- ///
- /// 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 ==(Point left, Point right)
- {
- return left.Equals(right);
- }
-
- ///
- /// Compares two objects for inequality.
- ///
- ///
- /// The on the left side of the operand.
- ///
- ///
- /// The on the right side of the operand.
- ///
- ///
- /// True if the current left is unequal to the parameter; otherwise, false.
- ///
- public static bool operator !=(Point left, Point right)
- {
- return !left.Equals(right);
- }
-
- ///
- /// Gets a representation for this .
- ///
- /// A representation for this object.
- public Vector2 ToVector2()
- {
- return new Vector2(this.X, this.Y);
- }
-
- ///
- /// Creates a rotation matrix for the given point and angle.
- ///
- /// The origin point to rotate around
- /// Rotation in degrees
- /// The rotation
- public static Matrix3x2 CreateRotation(Point origin, float degrees)
- {
- float radians = ImageMaths.DegreesToRadians(degrees);
- return Matrix3x2.CreateRotation(radians, origin.backingVector);
- }
-
- ///
- /// Rotates a point around a given a rotation matrix.
- ///
- /// The point to rotate
- /// Rotation matrix used
- /// The rotated
- public static Point Rotate(Point point, Matrix3x2 rotation)
- {
- return new Point(Vector2.Transform(point.backingVector, rotation));
- }
-
- ///
- /// Rotates a point around a given origin by the specified angle in degrees.
- ///
- /// The point to rotate
- /// The center point to rotate around.
- /// The angle in degrees.
- /// The rotated
- public static Point Rotate(Point point, Point origin, float degrees)
- {
- return new Point(Vector2.Transform(point.backingVector, CreateRotation(origin, degrees)));
- }
-
- ///
- /// Creates a skew matrix for the given point and angle.
- ///
- /// The origin point to rotate around
- /// The x-angle in degrees.
- /// The y-angle in degrees.
- /// The rotation
- public static Matrix3x2 CreateSkew(Point origin, float degreesX, float degreesY)
- {
- float radiansX = ImageMaths.DegreesToRadians(degreesX);
- float radiansY = ImageMaths.DegreesToRadians(degreesY);
- return Matrix3x2.CreateSkew(radiansX, radiansY, origin.backingVector);
- }
-
- ///
- /// Skews a point using a given a skew matrix.
- ///
- /// The point to rotate
- /// Rotation matrix used
- /// The rotated
- public static Point Skew(Point point, Matrix3x2 skew)
- {
- return new Point(Vector2.Transform(point.backingVector, skew));
- }
-
- ///
- /// Skews a point around a given origin by the specified angles in degrees.
- ///
- /// The point to skew.
- /// The center point to rotate around.
- /// The x-angle in degrees.
- /// The y-angle in degrees.
- /// The skewed
- public static Point Skew(Point point, Point origin, float degreesX, float degreesY)
- {
- return new Point(Vector2.Transform(point.backingVector, CreateSkew(origin, degreesX, degreesY)));
- }
-
- ///
- public override int GetHashCode()
- {
- return this.GetHashCode(this);
- }
-
- ///
- public override string ToString()
- {
- if (this.IsEmpty)
- {
- return "Point [ Empty ]";
- }
-
- return $"Point [ X={this.X}, Y={this.Y} ]";
- }
-
- ///
- public override bool Equals(object obj)
- {
- if (obj is Point)
- {
- return this.Equals((Point)obj);
- }
-
- return false;
- }
-
- ///
- public bool Equals(Point other)
- {
- return this.backingVector.Equals(other.backingVector);
- }
-
- ///
- /// 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(Point point)
- {
- return point.backingVector.GetHashCode();
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Numerics/Rectangle.cs b/src/ImageProcessorCore - Copy/Numerics/Rectangle.cs
deleted file mode 100644
index 6fe2c3a497..0000000000
--- a/src/ImageProcessorCore - Copy/Numerics/Rectangle.cs
+++ /dev/null
@@ -1,291 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.ComponentModel;
- using System.Numerics;
-
- ///
- /// Stores a set of four integers that represent the location and size of a rectangle.
- ///
- ///
- /// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
- /// as it avoids the need to create new values for modification operations.
- ///
- public struct Rectangle : IEquatable
- {
- ///
- /// Represents a that has X, Y, Width, and Height values set to zero.
- ///
- public static readonly Rectangle Empty = default(Rectangle);
-
- ///
- /// The backing vector for SIMD support.
- ///
- private Vector4 backingVector;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The horizontal position of the rectangle.
- /// The vertical position of the rectangle.
- /// The width of the rectangle.
- /// The height of the rectangle.
- public Rectangle(int x, int y, int width, int height)
- {
- this.backingVector = new Vector4(x, y, width, height);
- }
-
- ///
- /// Initializes a new instance of the struct.
- ///
- ///
- /// The which specifies the rectangles point in a two-dimensional plane.
- ///
- ///
- /// The which specifies the rectangles height and width.
- ///
- public Rectangle(Point point, Size size)
- {
- this.backingVector = new Vector4(point.X, point.Y, size.Width, size.Height);
- }
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The vector.
- public Rectangle(Vector4 vector)
- {
- this.backingVector = vector;
- }
-
- ///
- /// The x-coordinate of this .
- ///
- public int X
- {
- get
- {
- return (int)this.backingVector.X;
- }
-
- set
- {
- this.backingVector.X = value;
- }
- }
-
- ///
- /// The y-coordinate of this .
- ///
- public int Y
- {
- get
- {
- return (int)this.backingVector.Y;
- }
-
- set
- {
- this.backingVector.Y = value;
- }
- }
-
- ///
- /// The width of this .
- ///
- public int Width
- {
- get
- {
- return (int)this.backingVector.Z;
- }
-
- set
- {
- this.backingVector.Z = value;
- }
- }
-
- ///
- /// The height of this .
- ///
- public int Height
- {
- get
- {
- return (int)this.backingVector.W;
- }
-
- set
- {
- this.backingVector.W = value;
- }
- }
-
- ///
- /// Gets a value indicating whether this is empty.
- ///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public bool IsEmpty => this.Equals(Empty);
-
- ///
- /// Gets the y-coordinate of the top edge of this .
- ///
- public int Top => this.Y;
-
- ///
- /// Gets the x-coordinate of the right edge of this .
- ///
- public int Right => this.X + this.Width;
-
- ///
- /// Gets the y-coordinate of the bottom edge of this .
- ///
- public int Bottom => this.Y + this.Height;
-
- ///
- /// Gets the x-coordinate of the left edge of this .
- ///
- public int Left => this.X;
-
- ///
- /// Computes the sum of adding two rectangles.
- ///
- /// The rectangle on the left hand of the operand.
- /// The rectangle on the right hand of the operand.
- ///
- /// The
- ///
- public static Rectangle operator +(Rectangle left, Rectangle right)
- {
- return new Rectangle(left.backingVector + right.backingVector);
- }
-
- ///
- /// Computes the difference left by subtracting one rectangle from another.
- ///
- /// The rectangle on the left hand of the operand.
- /// The rectangle on the right hand of the operand.
- ///
- /// The
- ///
- public static Rectangle operator -(Rectangle left, Rectangle right)
- {
- return new Rectangle(left.backingVector - right.backingVector);
- }
-
- ///
- /// 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 ==(Rectangle left, Rectangle right)
- {
- return left.Equals(right);
- }
-
- ///
- /// Compares two objects for inequality.
- ///
- ///
- /// The on the left side of the operand.
- ///
- ///
- /// The on the right side of the operand.
- ///
- ///
- /// True if the current left is unequal to the parameter; otherwise, false.
- ///
- public static bool operator !=(Rectangle left, Rectangle right)
- {
- return !left.Equals(right);
- }
-
- ///
- /// Determines if the specfied point is contained within the rectangular region defined by
- /// this .
- ///
- /// The x-coordinate of the given point.
- /// The y-coordinate of the given point.
- /// The
- public bool Contains(int x, int y)
- {
- // TODO: SIMD?
- return this.X <= x
- && x < this.Right
- && this.Y <= y
- && y < this.Bottom;
- }
-
- ///
- /// Returns the center point of the given
- ///
- /// The rectangle
- ///
- public static Point Center(Rectangle rectangle)
- {
- return new Point(rectangle.Left + rectangle.Width / 2, rectangle.Top + rectangle.Height / 2);
- }
-
- ///
- public override int GetHashCode()
- {
- return this.GetHashCode(this);
- }
-
- ///
- public override string ToString()
- {
- if (this.IsEmpty)
- {
- return "Rectangle [ Empty ]";
- }
-
- return
- $"Rectangle [ X={this.X}, Y={this.Y}, Width={this.Width}, Height={this.Height} ]";
- }
-
- ///
- public override bool Equals(object obj)
- {
- if (obj is Rectangle)
- {
- return this.Equals((Rectangle)obj);
- }
-
- return false;
- }
-
- ///
- public bool Equals(Rectangle other)
- {
- return this.backingVector.Equals(other.backingVector);
- }
-
- ///
- /// 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(Rectangle rectangle)
- {
- return rectangle.backingVector.GetHashCode();
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Numerics/Size.cs b/src/ImageProcessorCore - Copy/Numerics/Size.cs
deleted file mode 100644
index 4b416b2182..0000000000
--- a/src/ImageProcessorCore - Copy/Numerics/Size.cs
+++ /dev/null
@@ -1,208 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.ComponentModel;
- using System.Numerics;
-
- ///
- /// Stores an ordered pair of integers, which specify a height and width.
- ///
- ///
- /// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
- /// as it avoids the need to create new values for modification operations.
- ///
- public struct Size : IEquatable
- {
- ///
- /// Represents a that has Width and Height values set to zero.
- ///
- public static readonly Size Empty = default(Size);
-
- ///
- /// The backing vector for SIMD support.
- ///
- private Vector2 backingVector;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The width of the size.
- /// The height of the size.
- public Size(int width, int height)
- {
- this.backingVector = new Vector2(width, height);
- }
-
- ///
- /// Initializes a new instance of the struct.
- ///
- ///
- /// The vector representing the width and height.
- ///
- public Size(Vector2 vector)
- {
- this.backingVector = new Vector2(vector.X, vector.Y);
- }
-
- ///
- /// The width of this .
- ///
- public int Width
- {
- get
- {
- return (int)this.backingVector.X;
- }
-
- set
- {
- this.backingVector.X = value;
- }
- }
-
- ///
- /// The height of this .
- ///
- public int Height
- {
- get
- {
- return (int)this.backingVector.Y;
- }
-
- set
- {
- this.backingVector.Y = value;
- }
- }
-
- ///
- /// Gets a value indicating whether this is empty.
- ///
- [EditorBrowsable(EditorBrowsableState.Never)]
- public bool IsEmpty => this.Equals(Empty);
-
- ///
- /// Computes the sum of adding two sizes.
- ///
- /// The size on the left hand of the operand.
- /// The size on the right hand of the operand.
- ///
- /// The
- ///
- public static Size operator +(Size left, Size right)
- {
- return new Size(left.backingVector + right.backingVector);
- }
-
- ///
- /// Computes the difference left by subtracting one size from another.
- ///
- /// The size on the left hand of the operand.
- /// The size on the right hand of the operand.
- ///
- /// The
- ///
- public static Size operator -(Size left, Size right)
- {
- return new Size(left.backingVector - right.backingVector);
- }
-
- ///
- /// 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 ==(Size left, Size right)
- {
- return left.Equals(right);
- }
-
- ///
- /// Compares two objects for inequality.
- ///
- ///
- /// The on the left side of the operand.
- ///
- ///
- /// The on the right side of the operand.
- ///
- ///
- /// True if the current left is unequal to the parameter; otherwise, false.
- ///
- public static bool operator !=(Size left, Size right)
- {
- return !left.Equals(right);
- }
-
- ///
- /// Gets a representation for this .
- ///
- /// A representation for this object.
- public Vector2 ToVector2()
- {
- return new Vector2(this.Width, this.Height);
- }
-
- ///
- public override int GetHashCode()
- {
- return this.GetHashCode(this);
- }
-
- ///
- public override string ToString()
- {
- if (this.IsEmpty)
- {
- return "Size [ Empty ]";
- }
-
- return
- $"Size [ Width={this.Width}, Height={this.Height} ]";
- }
-
- ///
- public override bool Equals(object obj)
- {
- if (obj is Size)
- {
- return this.Equals((Size)obj);
- }
-
- return false;
- }
-
- ///
- public bool Equals(Size other)
- {
- return this.backingVector.Equals(other.backingVector);
- }
-
- ///
- /// 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(Size size)
- {
- return size.backingVector.GetHashCode();
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/PackedVector/Bgra32.cs b/src/ImageProcessorCore - Copy/PackedVector/Bgra32.cs
deleted file mode 100644
index fc6a788b08..0000000000
--- a/src/ImageProcessorCore - Copy/PackedVector/Bgra32.cs
+++ /dev/null
@@ -1,168 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.Numerics;
-
- ///
- /// Packed vector type containing four 8-bit unsigned normalized values ranging from 0 to 1.
- ///
- public struct Bgra32 : IPackedVector, IEquatable
- {
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The blue component.
- /// The green component.
- /// The red component.
- /// The alpha component.
- public Bgra32(float b, float g, float r, float a)
- {
- 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 vector containing the components for the packed vector.
- ///
- public Bgra32(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 ==(Bgra32 left, Bgra32 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 !=(Bgra32 left, Bgra32 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 & 0xFF,
- (this.PackedValue >> 8) & 0xFF,
- (this.PackedValue >> 16) & 0xFF,
- (this.PackedValue >> 24) & 0xFF) / 255f;
- }
-
- ///
- public byte[] ToBytes()
- {
- return new[]
- {
- (byte)(this.PackedValue & 0xFF),
- (byte)((this.PackedValue >> 8) & 0xFF),
- (byte)((this.PackedValue >> 16) & 0xFF),
- (byte)((this.PackedValue >> 24) & 0xFF)
- };
- }
-
- ///
- public override bool Equals(object obj)
- {
- return (obj is Bgra32) && this.Equals((Bgra32)obj);
- }
-
- ///
- public bool Equals(Bgra32 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) |
- ((uint)Math.Round(vector.Y) << 8) |
- ((uint)Math.Round(vector.Z) << 16) |
- ((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(Bgra32 packed)
- {
- return packed.PackedValue.GetHashCode();
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/PackedVector/IPackedVector.cs b/src/ImageProcessorCore - Copy/PackedVector/IPackedVector.cs
deleted file mode 100644
index 02e10cc3a5..0000000000
--- a/src/ImageProcessorCore - Copy/PackedVector/IPackedVector.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- 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.
- /// Typically packed in least to greatest significance order.
- ///
- 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 vector components are typically expanded in least to greatest significance order.
- ///
- /// The .
- Vector4 ToVector4();
-
- ///
- /// Expands the packed representation into a .
- /// The bytes are typically expanded in least to greatest significance order.
- ///
- /// The .
- byte[] ToBytes();
- }
-}
diff --git a/src/ImageProcessorCore - Copy/PixelAccessor/Bgra32PixelAccessor.cs b/src/ImageProcessorCore - Copy/PixelAccessor/Bgra32PixelAccessor.cs
deleted file mode 100644
index cecc148b93..0000000000
--- a/src/ImageProcessorCore - Copy/PixelAccessor/Bgra32PixelAccessor.cs
+++ /dev/null
@@ -1,155 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.Runtime.InteropServices;
-
- ///
- /// Provides per-pixel access to an images pixels.
- ///
- ///
- /// The image data is always stored in format, where the blue, green, red, and
- /// alpha values are 8 bit unsigned bytes.
- ///
- public sealed unsafe class Bgra32PixelAccessor : IPixelAccessor
- {
- ///
- /// The position of the first pixel in the bitmap.
- ///
- private Bgra32* 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 Bgra32PixelAccessor(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 = (Bgra32*)this.pixelsHandle.AddrOfPinnedObject().ToPointer();
- }
-
- ///
- /// Finalizes an instance of the class.
- ///
- ~Bgra32PixelAccessor()
- {
- 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)) = (Bgra32)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/src/ImageProcessorCore - Copy/PixelAccessor/IPixelAccessor.cs b/src/ImageProcessorCore - Copy/PixelAccessor/IPixelAccessor.cs
deleted file mode 100644
index bf3a4067c4..0000000000
--- a/src/ImageProcessorCore - Copy/PixelAccessor/IPixelAccessor.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
-
- ///
- /// Encapsulates properties to provides per-pixel access to an images pixels.
- ///
- public interface IPixelAccessor : IDisposable
- {
- ///
- /// Gets the width of the image in pixels.
- ///
- int Width { get; }
-
- ///
- /// Gets the height of the image in pixels.
- ///
- int Height { get; }
-
- ///
- /// Gets or sets the 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.
- IPackedVector this[int x, int y]
- {
- get;
- set;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/ProgressEventArgs.cs b/src/ImageProcessorCore - Copy/ProgressEventArgs.cs
deleted file mode 100644
index 0f4c027f5e..0000000000
--- a/src/ImageProcessorCore - Copy/ProgressEventArgs.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// 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/src/ImageProcessorCore - Copy/Properties/AssemblyInfo.cs b/src/ImageProcessorCore - Copy/Properties/AssemblyInfo.cs
deleted file mode 100644
index ea81ff60c6..0000000000
--- a/src/ImageProcessorCore - Copy/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-using System.Resources;
-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: AssemblyTitle("ImageProcessorCore")]
-[assembly: AssemblyDescription("A cross-platform library for processing of image files written in C#")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("James Jackson-South")]
-[assembly: AssemblyProduct("ImageProcessorCore")]
-[assembly: AssemblyCopyright("Copyright (c) James Jackson-South and contributors.")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-[assembly: NeutralResourcesLanguage("en")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
-
-// Ensure the internals can be tested.
-[assembly: InternalsVisibleTo("ImageProcessorCore.Benchmarks")]
-[assembly: InternalsVisibleTo("ImageProcessorCore.Tests")]
diff --git a/src/ImageProcessorCore - Copy/Quantizers/IQuantizer.cs b/src/ImageProcessorCore - Copy/Quantizers/IQuantizer.cs
deleted file mode 100644
index 3196ebf9f1..0000000000
--- a/src/ImageProcessorCore - Copy/Quantizers/IQuantizer.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Quantizers
-{
- ///
- /// Provides methods for allowing quantization of images pixels.
- ///
- public interface IQuantizer
- {
- ///
- /// Gets or sets the transparency threshold.
- ///
- byte Threshold { get; set; }
-
- ///
- /// Quantize an image and return the resulting output pixels.
- ///
- /// The image to quantize.
- /// The maximum number of colors to return.
- ///
- /// A representing a quantized version of the image pixels.
- ///
- QuantizedImage Quantize(ImageBase image, int maxColors);
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Quantizers/Octree/OctreeQuantizer.cs b/src/ImageProcessorCore - Copy/Quantizers/Octree/OctreeQuantizer.cs
deleted file mode 100644
index c0c900145b..0000000000
--- a/src/ImageProcessorCore - Copy/Quantizers/Octree/OctreeQuantizer.cs
+++ /dev/null
@@ -1,534 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Quantizers
-{
- using System;
- using System.Collections.Generic;
-
- ///
- /// Encapsulates methods to calculate the colour palette if an image using an Octree pattern.
- ///
- ///
- public sealed class OctreeQuantizer : Quantizer
- {
- ///
- /// Stores the tree
- ///
- private Octree octree;
-
- ///
- /// Maximum allowed color depth
- ///
- private int colors;
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The Octree quantizer is a two pass algorithm. The initial pass sets up the Octree,
- /// the second pass quantizes a color based on the nodes in the tree
- ///
- public OctreeQuantizer()
- : base(false)
- {
- }
-
- ///
- public override QuantizedImage Quantize(ImageBase image, int maxColors)
- {
- this.colors = maxColors.Clamp(1, 255);
-
- if (this.octree == null)
- {
- // Construct the Octree
- this.octree = new Octree(this.GetBitsNeededForColorDepth(maxColors));
- }
-
- return base.Quantize(image, maxColors);
- }
-
- ///
- /// Process the pixel in the first pass of the algorithm
- ///
- ///
- /// The pixel to quantize
- ///
- ///
- /// This function need only be overridden if your quantize algorithm needs two passes,
- /// such as an Octree quantizer.
- ///
- protected override void InitialQuantizePixel(Bgra32 pixel)
- {
- // Add the color to the Octree
- this.octree.AddColor(pixel);
- }
-
- ///
- /// Override this to process the pixel in the second pass of the algorithm
- ///
- ///
- /// The pixel to quantize
- ///
- ///
- /// The quantized value
- ///
- protected override byte QuantizePixel(Bgra32 pixel)
- {
- // The color at [maxColors] is set to transparent
- byte paletteIndex = (byte)this.colors;
-
- // Get the palette index if it's transparency meets criterea.
- if (pixel.A > this.Threshold)
- {
- paletteIndex = (byte)this.octree.GetPaletteIndex(pixel);
- }
-
- return paletteIndex;
- }
-
- ///
- /// Retrieve the palette for the quantized image.
- ///
- ///
- /// The new color palette
- ///
- protected override List GetPalette()
- {
- // First off convert the Octree to maxColors colors
- List palette = this.octree.Palletize(Math.Max(this.colors, 1));
-
- palette.Add(Bgra32.Empty);
- this.TransparentIndex = this.colors;
-
- return palette;
- }
-
- ///
- /// Returns how many bits are required to store the specified number of colors.
- /// Performs a Log2() on the value.
- ///
- /// The number of colors.
- ///
- /// The
- ///
- private int GetBitsNeededForColorDepth(int colorCount)
- {
- return (int)Math.Ceiling(Math.Log(colorCount, 2));
- }
-
- ///
- /// Class which does the actual quantization
- ///
- private class Octree
- {
- ///
- /// Mask used when getting the appropriate pixels for a given node
- ///
- private static readonly int[] Mask = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
-
- ///
- /// The root of the Octree
- ///
- private readonly OctreeNode root;
-
- ///
- /// Array of reducible nodes
- ///
- private readonly OctreeNode[] reducibleNodes;
-
- ///
- /// Maximum number of significant bits in the image
- ///
- private readonly int maxColorBits;
-
- ///
- /// Store the last node quantized
- ///
- private OctreeNode previousNode;
-
- ///
- /// Cache the previous color quantized
- ///
- private int previousColor;
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The maximum number of significant bits in the image
- ///
- public Octree(int maxColorBits)
- {
- this.maxColorBits = maxColorBits;
- this.Leaves = 0;
- this.reducibleNodes = new OctreeNode[9];
- this.root = new OctreeNode(0, this.maxColorBits, this);
- this.previousColor = 0;
- this.previousNode = null;
- }
-
- ///
- /// Gets or sets the number of leaves in the tree
- ///
- private int Leaves { get; set; }
-
- ///
- /// Gets the array of reducible nodes
- ///
- private OctreeNode[] ReducibleNodes => this.reducibleNodes;
-
- ///
- /// Add a given color value to the Octree
- ///
- ///
- /// The containing color information to add.
- ///
- public void AddColor(Bgra32 pixel)
- {
- // Check if this request is for the same color as the last
- if (this.previousColor == pixel.Bgra)
- {
- // If so, check if I have a previous node setup. This will only occur if the first color in the image
- // happens to be black, with an alpha component of zero.
- if (this.previousNode == null)
- {
- this.previousColor = pixel.Bgra;
- this.root.AddColor(pixel, this.maxColorBits, 0, this);
- }
- else
- {
- // Just update the previous node
- this.previousNode.Increment(pixel);
- }
- }
- else
- {
- this.previousColor = pixel.Bgra;
- this.root.AddColor(pixel, this.maxColorBits, 0, this);
- }
- }
-
- ///
- /// Convert the nodes in the Octree to a palette with a maximum of colorCount colors
- ///
- ///
- /// The maximum number of colors
- ///
- ///
- /// An with the palletized colors
- ///
- public List Palletize(int colorCount)
- {
- while (this.Leaves > colorCount)
- {
- this.Reduce();
- }
-
- // Now palletize the nodes
- List palette = new List(this.Leaves);
- int paletteIndex = 0;
- this.root.ConstructPalette(palette, ref paletteIndex);
-
- // And return the palette
- return palette;
- }
-
- ///
- /// Get the palette index for the passed color
- ///
- ///
- /// The containing the pixel data.
- ///
- ///
- /// The index of the given structure.
- ///
- public int GetPaletteIndex(Bgra32 pixel)
- {
- return this.root.GetPaletteIndex(pixel, 0);
- }
-
- ///
- /// Keep track of the previous node that was quantized
- ///
- ///
- /// The node last quantized
- ///
- protected void TrackPrevious(OctreeNode node)
- {
- this.previousNode = node;
- }
-
- ///
- /// Reduce the depth of the tree
- ///
- private void Reduce()
- {
- // Find the deepest level containing at least one reducible node
- int index = this.maxColorBits - 1;
- while ((index > 0) && (this.reducibleNodes[index] == null))
- {
- index--;
- }
-
- // Reduce the node most recently added to the list at level 'index'
- OctreeNode node = this.reducibleNodes[index];
- this.reducibleNodes[index] = node.NextReducible;
-
- // Decrement the leaf count after reducing the node
- this.Leaves -= node.Reduce();
-
- // And just in case I've reduced the last color to be added, and the next color to
- // be added is the same, invalidate the previousNode...
- this.previousNode = null;
- }
-
- ///
- /// Class which encapsulates each node in the tree
- ///
- protected class OctreeNode
- {
- ///
- /// Pointers to any child nodes
- ///
- private readonly OctreeNode[] children;
-
- ///
- /// Flag indicating that this is a leaf node
- ///
- private bool leaf;
-
- ///
- /// Number of pixels in this node
- ///
- private int pixelCount;
-
- ///
- /// Red component
- ///
- private int red;
-
- ///
- /// Green Component
- ///
- private int green;
-
- ///
- /// Blue component
- ///
- private int blue;
-
- ///
- /// The index of this node in the palette
- ///
- private int paletteIndex;
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The level in the tree = 0 - 7
- ///
- ///
- /// The number of significant color bits in the image
- ///
- ///
- /// The tree to which this node belongs
- ///
- public OctreeNode(int level, int colorBits, Octree octree)
- {
- // Construct the new node
- this.leaf = level == colorBits;
-
- this.red = this.green = this.blue = 0;
- this.pixelCount = 0;
-
- // If a leaf, increment the leaf count
- if (this.leaf)
- {
- octree.Leaves++;
- this.NextReducible = null;
- this.children = null;
- }
- else
- {
- // Otherwise add this to the reducible nodes
- this.NextReducible = octree.ReducibleNodes[level];
- octree.ReducibleNodes[level] = this;
- this.children = new OctreeNode[8];
- }
- }
-
- ///
- /// Gets the next reducible node
- ///
- public OctreeNode NextReducible { get; }
-
- ///
- /// Add a color into the tree
- ///
- ///
- /// The color
- ///
- ///
- /// The number of significant color bits
- ///
- ///
- /// The level in the tree
- ///
- ///
- /// The tree to which this node belongs
- ///
- public void AddColor(Bgra32 pixel, int colorBits, int level, Octree octree)
- {
- // Update the color information if this is a leaf
- if (this.leaf)
- {
- this.Increment(pixel);
-
- // Setup the previous node
- octree.TrackPrevious(this);
- }
- else
- {
- // Go to the next level down in the tree
- int shift = 7 - level;
- int index = ((pixel.R & Mask[level]) >> (shift - 2)) |
- ((pixel.G & Mask[level]) >> (shift - 1)) |
- ((pixel.B & Mask[level]) >> shift);
-
- OctreeNode child = this.children[index];
-
- if (child == null)
- {
- // Create a new child node and store it in the array
- child = new OctreeNode(level + 1, colorBits, octree);
- this.children[index] = child;
- }
-
- // Add the color to the child node
- child.AddColor(pixel, colorBits, level + 1, octree);
- }
- }
-
- ///
- /// Reduce this node by removing all of its children
- ///
- /// The number of leaves removed
- public int Reduce()
- {
- this.red = this.green = this.blue = 0;
- int childNodes = 0;
-
- // Loop through all children and add their information to this node
- for (int index = 0; index < 8; index++)
- {
- if (this.children[index] != null)
- {
- this.red += this.children[index].red;
- this.green += this.children[index].green;
- this.blue += this.children[index].blue;
- this.pixelCount += this.children[index].pixelCount;
- ++childNodes;
- this.children[index] = null;
- }
- }
-
- // Now change this to a leaf node
- this.leaf = true;
-
- // Return the number of nodes to decrement the leaf count by
- return childNodes - 1;
- }
-
- ///
- /// Traverse the tree, building up the color palette
- ///
- ///
- /// The palette
- ///
- ///
- /// The current palette index
- ///
- public void ConstructPalette(List palette, ref int index)
- {
- if (this.leaf)
- {
- // Consume the next palette index
- this.paletteIndex = index++;
-
- byte r = (this.red / this.pixelCount).ToByte();
- byte g = (this.green / this.pixelCount).ToByte();
- byte b = (this.blue / this.pixelCount).ToByte();
-
- // And set the color of the palette entry
- palette.Add(new Bgra32(b, g, r));
- }
- else
- {
- // Loop through children looking for leaves
- for (int i = 0; i < 8; i++)
- {
- if (this.children[i] != null)
- {
- this.children[i].ConstructPalette(palette, ref index);
- }
- }
- }
- }
-
- ///
- /// Return the palette index for the passed color
- ///
- ///
- /// The representing the pixel.
- ///
- ///
- /// The level.
- ///
- ///
- /// The representing the index of the pixel in the palette.
- ///
- public int GetPaletteIndex(Bgra32 pixel, int level)
- {
- int index = this.paletteIndex;
-
- if (!this.leaf)
- {
- int shift = 7 - level;
- int pixelIndex = ((pixel.R & Mask[level]) >> (shift - 2)) |
- ((pixel.G & Mask[level]) >> (shift - 1)) |
- ((pixel.B & Mask[level]) >> shift);
-
- if (this.children[pixelIndex] != null)
- {
- index = this.children[pixelIndex].GetPaletteIndex(pixel, level + 1);
- }
- else
- {
- throw new Exception("Didn't expect this!");
- }
- }
-
- return index;
- }
-
- ///
- /// Increment the pixel count and add to the color information
- ///
- ///
- /// The pixel to add.
- ///
- public void Increment(Bgra32 pixel)
- {
- this.pixelCount++;
- this.red += pixel.R;
- this.green += pixel.G;
- this.blue += pixel.B;
- }
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Quantizers/Octree/Quantizer.cs b/src/ImageProcessorCore - Copy/Quantizers/Octree/Quantizer.cs
deleted file mode 100644
index 40d281015c..0000000000
--- a/src/ImageProcessorCore - Copy/Quantizers/Octree/Quantizer.cs
+++ /dev/null
@@ -1,146 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Quantizers
-{
- using System.Collections.Generic;
- using System.Threading.Tasks;
-
- ///
- /// Encapsulates methods to calculate the color palette of an image.
- ///
- public abstract class Quantizer : IQuantizer
- {
- ///
- /// Flag used to indicate whether a single pass or two passes are needed for quantization.
- ///
- private readonly bool singlePass;
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// If true, the quantization only needs to loop through the source pixels once
- ///
- ///
- /// If you construct this class with a true value for singlePass, then the code will, when quantizing your image,
- /// only call the 'QuantizeImage' function. If two passes are required, the code will call 'InitialQuantizeImage'
- /// and then 'QuantizeImage'.
- ///
- protected Quantizer(bool singlePass)
- {
- this.singlePass = singlePass;
- }
-
- ///
- /// Gets or sets the transparency index.
- ///
- public int TransparentIndex { get; protected set; } = -1;
-
- ///
- public byte Threshold { get; set; }
-
- ///
- public virtual QuantizedImage Quantize(ImageBase image, int maxColors)
- {
- Guard.NotNull(image, nameof(image));
-
- // Get the size of the source image
- int height = image.Height;
- int width = image.Width;
- byte[] quantizedPixels = new byte[width * height];
- List palette;
-
- using (PixelAccessor pixels = image.Lock())
- {
- // Call the FirstPass function if not a single pass algorithm.
- // For something like an Octree quantizer, this will run through
- // all image pixels, build a data structure, and create a palette.
- if (!this.singlePass)
- {
- this.FirstPass(pixels, width, height);
- }
-
- // Get the palette
- palette = this.GetPalette();
-
- this.SecondPass(pixels, quantizedPixels, width, height);
- }
-
- return new QuantizedImage(width, height, palette.ToArray(), quantizedPixels, this.TransparentIndex);
- }
-
- ///
- /// Execute the first pass through the pixels in the image
- ///
- /// The source data
- /// The width in pixels of the image.
- /// The height in pixels of the image.
- protected virtual void FirstPass(PixelAccessor source, int width, int height)
- {
- // Loop through each row
- for (int y = 0; y < height; y++)
- {
- // And loop through each column
- for (int x = 0; x < width; x++)
- {
- // Now I have the pixel, call the FirstPassQuantize function...
- this.InitialQuantizePixel(source[x, y]);
- }
- }
- }
-
- ///
- /// Execute a second pass through the bitmap
- ///
- /// The source image.
- /// The output pixel array
- /// The width in pixels of the image
- /// The height in pixels of the image
- protected virtual void SecondPass(PixelAccessor source, byte[] output, int width, int height)
- {
- Parallel.For(
- 0,
- source.Height,
- y =>
- {
- for (int x = 0; x < source.Width; x++)
- {
- Bgra32 sourcePixel = source[x, y];
- output[(y * source.Width) + x] = this.QuantizePixel(sourcePixel);
- }
- });
- }
-
- ///
- /// Override this to process the pixel in the first pass of the algorithm
- ///
- /// The pixel to quantize
- ///
- /// This function need only be overridden if your quantize algorithm needs two passes,
- /// such as an Octree quantizer.
- ///
- protected virtual void InitialQuantizePixel(Bgra32 pixel)
- {
- }
-
- ///
- /// Override this to process the pixel in the second pass of the algorithm
- ///
- /// The pixel to quantize
- ///
- /// The quantized value
- ///
- protected abstract byte QuantizePixel(Bgra32 pixel);
-
- ///
- /// Retrieve the palette for the quantized image
- ///
- ///
- /// The new color palette
- ///
- protected abstract List GetPalette();
- }
-}
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/Quantizers/Palette/PaletteQuantizer.cs b/src/ImageProcessorCore - Copy/Quantizers/Palette/PaletteQuantizer.cs
deleted file mode 100644
index db2a4c59cb..0000000000
--- a/src/ImageProcessorCore - Copy/Quantizers/Palette/PaletteQuantizer.cs
+++ /dev/null
@@ -1,134 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Quantizers
-{
- using System;
- using System.Collections.Concurrent;
- using System.Collections.Generic;
- using System.Linq;
-
- ///
- /// Encapsulates methods to create a quantized image based upon the given palette.
- ///
- ///
- public class PaletteQuantizer : Quantizer
- {
- ///
- /// A lookup table for colors
- ///
- private readonly ConcurrentDictionary colorMap = new ConcurrentDictionary();
-
- ///
- /// List of all colors in the palette
- ///
- private Bgra32[] colors;
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The color palette. If none is given this will default to the web safe colors defined
- /// in the CSS Color Module Level 4.
- ///
- public PaletteQuantizer(Color[] palette = null)
- : base(true)
- {
- if (palette == null)
- {
- List safe = ColorConstants.WebSafeColors.Select(c => (Bgra32)c).ToList();
- safe.Insert(0, Bgra32.Empty);
- this.colors = safe.ToArray();
- }
- else
- {
- this.colors = palette.Select(c => (Bgra32)c).ToArray();
- }
- }
-
- ///
- public override QuantizedImage Quantize(ImageBase image, int maxColors)
- {
- Array.Resize(ref this.colors, maxColors.Clamp(1, 256));
- return base.Quantize(image, maxColors);
- }
-
- ///
- protected override byte QuantizePixel(Bgra32 pixel)
- {
- byte colorIndex = 0;
- string colorHash = pixel.ToString();
-
- // Check if the color is in the lookup table
- if (this.colorMap.ContainsKey(colorHash))
- {
- colorIndex = this.colorMap[colorHash];
- }
- else
- {
- // Not found - loop through the palette and find the nearest match.
- // Firstly check the alpha value - if less than the threshold, lookup the transparent color
- if (!(pixel.A > this.Threshold))
- {
- // Transparent. Lookup the first color with an alpha value of 0
- for (int index = 0; index < this.colors.Length; index++)
- {
- if (this.colors[index].A == 0)
- {
- colorIndex = (byte)index;
- this.TransparentIndex = colorIndex;
- break;
- }
- }
- }
- else
- {
- // Not transparent...
- int leastDistance = int.MaxValue;
- int red = pixel.R;
- int green = pixel.G;
- int blue = pixel.B;
-
- // Loop through the entire palette, looking for the closest color match
- for (int index = 0; index < this.colors.Length; index++)
- {
- Bgra32 paletteColor = this.colors[index];
-
- int redDistance = paletteColor.R - red;
- int greenDistance = paletteColor.G - green;
- int blueDistance = paletteColor.B - blue;
-
- int distance = (redDistance * redDistance) +
- (greenDistance * greenDistance) +
- (blueDistance * blueDistance);
-
- if (distance < leastDistance)
- {
- colorIndex = (byte)index;
- leastDistance = distance;
-
- // And if it's an exact match, exit the loop
- if (distance == 0)
- {
- break;
- }
- }
- }
- }
-
- // Now I have the color, pop it into the cache for next time
- this.colorMap.TryAdd(colorHash, colorIndex);
- }
-
- return colorIndex;
- }
-
- ///
- protected override List GetPalette()
- {
- return this.colors.ToList();
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Quantizers/QuantizedImage.cs b/src/ImageProcessorCore - Copy/Quantizers/QuantizedImage.cs
deleted file mode 100644
index fdf93abd33..0000000000
--- a/src/ImageProcessorCore - Copy/Quantizers/QuantizedImage.cs
+++ /dev/null
@@ -1,98 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Quantizers
-{
- using System;
- using System.Threading.Tasks;
-
- ///
- /// Represents a quantized image where the pixels indexed by a color palette.
- ///
- public class QuantizedImage
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The image width.
- /// The image height.
- /// The color palette.
- /// The quantized pixels.
- /// The transparency index.
- public QuantizedImage(int width, int height, Bgra32[] palette, byte[] pixels, int transparentIndex = -1)
- {
- Guard.MustBeGreaterThan(width, 0, nameof(width));
- Guard.MustBeGreaterThan(height, 0, nameof(height));
- Guard.NotNull(palette, nameof(palette));
- Guard.NotNull(pixels, nameof(pixels));
-
- if (pixels.Length != width * height)
- {
- throw new ArgumentException(
- $"Pixel array size must be {nameof(width)} * {nameof(height)}", nameof(pixels));
- }
-
- this.Width = width;
- this.Height = height;
- this.Palette = palette;
- this.Pixels = pixels;
- this.TransparentIndex = transparentIndex;
- }
-
- ///
- /// Gets the width of this .
- ///
- public int Width { get; }
-
- ///
- /// Gets the height of this .
- ///
- public int Height { get; }
-
- ///
- /// Gets the color palette of this .
- ///
- public Bgra32[] Palette { get; }
-
- ///
- /// Gets the pixels of this .
- ///
- public byte[] Pixels { get; }
-
- ///
- /// Gets the transparent index
- ///
- public int TransparentIndex { get; }
-
- ///
- /// Converts this quantized image to a normal image.
- ///
- ///
- /// The
- ///
- public Image ToImage()
- {
- Image image = new Image();
-
- int pixelCount = this.Pixels.Length;
- int palletCount = this.Palette.Length - 1;
- float[] bgraPixels = new float[pixelCount * 4];
-
- Parallel.For(0, pixelCount,
- i =>
- {
- int offset = i * 4;
- Color color = this.Palette[Math.Min(palletCount, this.Pixels[i])];
- bgraPixels[offset] = color.R;
- bgraPixels[offset + 1] = color.G;
- bgraPixels[offset + 2] = color.B;
- bgraPixels[offset + 3] = color.A;
- });
-
- image.SetPixels(this.Width, this.Height, bgraPixels);
- return image;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Quantizers/Wu/Box.cs b/src/ImageProcessorCore - Copy/Quantizers/Wu/Box.cs
deleted file mode 100644
index b9300b0870..0000000000
--- a/src/ImageProcessorCore - Copy/Quantizers/Wu/Box.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Quantizers
-{
- ///
- /// Represents a box color cube.
- ///
- internal sealed class Box
- {
- ///
- /// Gets or sets the min red value, exclusive.
- ///
- public int R0 { get; set; }
-
- ///
- /// Gets or sets the max red value, inclusive.
- ///
- public int R1 { get; set; }
-
- ///
- /// Gets or sets the min green value, exclusive.
- ///
- public int G0 { get; set; }
-
- ///
- /// Gets or sets the max green value, inclusive.
- ///
- public int G1 { get; set; }
-
- ///
- /// Gets or sets the min blue value, exclusive.
- ///
- public int B0 { get; set; }
-
- ///
- /// Gets or sets the max blue value, inclusive.
- ///
- public int B1 { get; set; }
-
- ///
- /// Gets or sets the min alpha value, exclusive.
- ///
- public int A0 { get; set; }
-
- ///
- /// Gets or sets the max alpha value, inclusive.
- ///
- public int A1 { get; set; }
-
- ///
- /// Gets or sets the volume.
- ///
- public int Volume { get; set; }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Quantizers/Wu/WuQuantizer.cs b/src/ImageProcessorCore - Copy/Quantizers/Wu/WuQuantizer.cs
deleted file mode 100644
index c06262503d..0000000000
--- a/src/ImageProcessorCore - Copy/Quantizers/Wu/WuQuantizer.cs
+++ /dev/null
@@ -1,786 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Quantizers
-{
- using System;
- using System.Collections.Generic;
- using System.Threading.Tasks;
-
- ///
- /// An implementation of Wu's color quantizer with alpha channel.
- ///
- ///
- ///
- /// Based on C Implementation of Xiaolin Wu's Color Quantizer (v. 2)
- /// (see Graphics Gems volume II, pages 126-133)
- /// ().
- ///
- ///
- /// This adaptation is based on the excellent JeremyAnsel.ColorQuant by Jérémy Ansel
- ///
- ///
- ///
- /// Algorithm: Greedy orthogonal bipartition of RGB space for variance
- /// minimization aided by inclusion-exclusion tricks.
- /// For speed no nearest neighbor search is done. Slightly
- /// better performance can be expected by more sophisticated
- /// but more expensive versions.
- ///
- ///
- public sealed class WuQuantizer : IQuantizer
- {
- ///
- /// The epsilon for comparing floating point numbers.
- ///
- private const float Epsilon = 0.001f;
-
- ///
- /// The index bits.
- ///
- private const int IndexBits = 6;
-
- ///
- /// The index alpha bits.
- ///
- private const int IndexAlphaBits = 3;
-
- ///
- /// The index count.
- ///
- private const int IndexCount = (1 << IndexBits) + 1;
-
- ///
- /// The index alpha count.
- ///
- private const int IndexAlphaCount = (1 << IndexAlphaBits) + 1;
-
- ///
- /// The table length.
- ///
- private const int TableLength = IndexCount * IndexCount * IndexCount * IndexAlphaCount;
-
- ///
- /// Moment of P(c).
- ///
- private readonly long[] vwt;
-
- ///
- /// Moment of r*P(c).
- ///
- private readonly long[] vmr;
-
- ///
- /// Moment of g*P(c).
- ///
- private readonly long[] vmg;
-
- ///
- /// Moment of b*P(c).
- ///
- private readonly long[] vmb;
-
- ///
- /// Moment of a*P(c).
- ///
- private readonly long[] vma;
-
- ///
- /// Moment of c^2*P(c).
- ///
- private readonly double[] m2;
-
- ///
- /// Color space tag.
- ///
- private readonly byte[] tag;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public WuQuantizer()
- {
- this.vwt = new long[TableLength];
- this.vmr = new long[TableLength];
- this.vmg = new long[TableLength];
- this.vmb = new long[TableLength];
- this.vma = new long[TableLength];
- this.m2 = new double[TableLength];
- this.tag = new byte[TableLength];
- }
-
- ///
- public byte Threshold { get; set; }
-
- ///
- public QuantizedImage Quantize(ImageBase image, int maxColors)
- {
- Guard.NotNull(image, nameof(image));
-
- int colorCount = maxColors.Clamp(1, 256);
-
- this.Clear();
-
- using (PixelAccessor imagePixels = image.Lock())
- {
- this.Build3DHistogram(imagePixels);
- this.Get3DMoments();
-
- Box[] cube;
- this.BuildCube(out cube, ref colorCount);
-
- return this.GenerateResult(imagePixels, colorCount, cube);
- }
- }
-
- ///
- /// Gets an index.
- ///
- /// The red value.
- /// The green value.
- /// The blue value.
- /// The alpha value.
- /// The index.
- private static int GetPaletteIndex(int r, int g, int b, int a)
- {
- return (r << ((IndexBits * 2) + IndexAlphaBits))
- + (r << (IndexBits + IndexAlphaBits + 1))
- + (g << (IndexBits + IndexAlphaBits))
- + (r << (IndexBits * 2))
- + (r << (IndexBits + 1))
- + (g << IndexBits)
- + ((r + g + b) << IndexAlphaBits)
- + r + g + b + a;
- }
-
- ///
- /// Computes sum over a box of any given statistic.
- ///
- /// The cube.
- /// The moment.
- /// The result.
- private static double Volume(Box cube, long[] moment)
- {
- return moment[GetPaletteIndex(cube.R1, cube.G1, cube.B1, cube.A1)]
- - moment[GetPaletteIndex(cube.R1, cube.G1, cube.B1, cube.A0)]
- - moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A1)]
- + moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
- - moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A1)]
- + moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
- + moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
- - moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
- - moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A1)]
- + moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
- + moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
- - moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
- + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
- - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
- - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
- + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
- }
-
- ///
- /// Computes part of Volume(cube, moment) that doesn't depend on r1, g1, or b1 (depending on direction).
- ///
- /// The cube.
- /// The direction.
- /// The moment.
- /// The result.
- private static long Bottom(Box cube, int direction, long[] moment)
- {
- switch (direction)
- {
- // Red
- case 0:
- return -moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A1)]
- + moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
- + moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
- - moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
- + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
- - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
- - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
- + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
-
- // Green
- case 1:
- return -moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A1)]
- + moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
- + moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
- - moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
- + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
- - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
- - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
- + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
-
- // Blue
- case 2:
- return -moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A1)]
- + moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
- + moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
- - moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
- + moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
- - moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
- - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
- + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
-
- // Alpha
- case 3:
- return -moment[GetPaletteIndex(cube.R1, cube.G1, cube.B1, cube.A0)]
- + moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
- + moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
- - moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
- + moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
- - moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
- - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
- + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
-
- default:
- throw new ArgumentOutOfRangeException(nameof(direction));
- }
- }
-
- ///
- /// Computes remainder of Volume(cube, moment), substituting position for r1, g1, or b1 (depending on direction).
- ///
- /// The cube.
- /// The direction.
- /// The position.
- /// The moment.
- /// The result.
- private static long Top(Box cube, int direction, int position, long[] moment)
- {
- switch (direction)
- {
- // Red
- case 0:
- return moment[GetPaletteIndex(position, cube.G1, cube.B1, cube.A1)]
- - moment[GetPaletteIndex(position, cube.G1, cube.B1, cube.A0)]
- - moment[GetPaletteIndex(position, cube.G1, cube.B0, cube.A1)]
- + moment[GetPaletteIndex(position, cube.G1, cube.B0, cube.A0)]
- - moment[GetPaletteIndex(position, cube.G0, cube.B1, cube.A1)]
- + moment[GetPaletteIndex(position, cube.G0, cube.B1, cube.A0)]
- + moment[GetPaletteIndex(position, cube.G0, cube.B0, cube.A1)]
- - moment[GetPaletteIndex(position, cube.G0, cube.B0, cube.A0)];
-
- // Green
- case 1:
- return moment[GetPaletteIndex(cube.R1, position, cube.B1, cube.A1)]
- - moment[GetPaletteIndex(cube.R1, position, cube.B1, cube.A0)]
- - moment[GetPaletteIndex(cube.R1, position, cube.B0, cube.A1)]
- + moment[GetPaletteIndex(cube.R1, position, cube.B0, cube.A0)]
- - moment[GetPaletteIndex(cube.R0, position, cube.B1, cube.A1)]
- + moment[GetPaletteIndex(cube.R0, position, cube.B1, cube.A0)]
- + moment[GetPaletteIndex(cube.R0, position, cube.B0, cube.A1)]
- - moment[GetPaletteIndex(cube.R0, position, cube.B0, cube.A0)];
-
- // Blue
- case 2:
- return moment[GetPaletteIndex(cube.R1, cube.G1, position, cube.A1)]
- - moment[GetPaletteIndex(cube.R1, cube.G1, position, cube.A0)]
- - moment[GetPaletteIndex(cube.R1, cube.G0, position, cube.A1)]
- + moment[GetPaletteIndex(cube.R1, cube.G0, position, cube.A0)]
- - moment[GetPaletteIndex(cube.R0, cube.G1, position, cube.A1)]
- + moment[GetPaletteIndex(cube.R0, cube.G1, position, cube.A0)]
- + moment[GetPaletteIndex(cube.R0, cube.G0, position, cube.A1)]
- - moment[GetPaletteIndex(cube.R0, cube.G0, position, cube.A0)];
-
- // Alpha
- case 3:
- return moment[GetPaletteIndex(cube.R1, cube.G1, cube.B1, position)]
- - moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, position)]
- - moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, position)]
- + moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, position)]
- - moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, position)]
- + moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, position)]
- + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, position)]
- - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, position)];
-
- default:
- throw new ArgumentOutOfRangeException(nameof(direction));
- }
- }
-
- ///
- /// Clears the tables.
- ///
- private void Clear()
- {
- Array.Clear(this.vwt, 0, TableLength);
- Array.Clear(this.vmr, 0, TableLength);
- Array.Clear(this.vmg, 0, TableLength);
- Array.Clear(this.vmb, 0, TableLength);
- Array.Clear(this.vma, 0, TableLength);
- Array.Clear(this.m2, 0, TableLength);
-
- Array.Clear(this.tag, 0, TableLength);
- }
-
- ///
- /// Builds a 3-D color histogram of counts, r/g/b, c^2.
- ///
- /// The image.
- private void Build3DHistogram(PixelAccessor image)
- {
- for (int y = 0; y < image.Height; y++)
- {
- for (int x = 0; x < image.Width; x++)
- {
- Bgra32 color = image[x, y];
-
- byte r = color.R;
- byte g = color.G;
- byte b = color.B;
- byte a = color.A;
-
- int inr = r >> (8 - IndexBits);
- int ing = g >> (8 - IndexBits);
- int inb = b >> (8 - IndexBits);
- int ina = a >> (8 - IndexAlphaBits);
-
- int ind = GetPaletteIndex(inr + 1, ing + 1, inb + 1, ina + 1);
-
- this.vwt[ind]++;
- this.vmr[ind] += r;
- this.vmg[ind] += g;
- this.vmb[ind] += b;
- this.vma[ind] += a;
- this.m2[ind] += (r * r) + (g * g) + (b * b) + (a * a);
- }
- }
- }
-
- ///
- /// Converts the histogram into moments so that we can rapidly calculate
- /// the sums of the above quantities over any desired box.
- ///
- private void Get3DMoments()
- {
- long[] volume = new long[IndexCount * IndexAlphaCount];
- long[] volumeR = new long[IndexCount * IndexAlphaCount];
- long[] volumeG = new long[IndexCount * IndexAlphaCount];
- long[] volumeB = new long[IndexCount * IndexAlphaCount];
- long[] volumeA = new long[IndexCount * IndexAlphaCount];
- double[] volume2 = new double[IndexCount * IndexAlphaCount];
-
- long[] area = new long[IndexAlphaCount];
- long[] areaR = new long[IndexAlphaCount];
- long[] areaG = new long[IndexAlphaCount];
- long[] areaB = new long[IndexAlphaCount];
- long[] areaA = new long[IndexAlphaCount];
- double[] area2 = new double[IndexAlphaCount];
-
- for (int r = 1; r < IndexCount; r++)
- {
- Array.Clear(volume, 0, IndexCount * IndexAlphaCount);
- Array.Clear(volumeR, 0, IndexCount * IndexAlphaCount);
- Array.Clear(volumeG, 0, IndexCount * IndexAlphaCount);
- Array.Clear(volumeB, 0, IndexCount * IndexAlphaCount);
- Array.Clear(volumeA, 0, IndexCount * IndexAlphaCount);
- Array.Clear(volume2, 0, IndexCount * IndexAlphaCount);
-
- for (int g = 1; g < IndexCount; g++)
- {
- Array.Clear(area, 0, IndexAlphaCount);
- Array.Clear(areaR, 0, IndexAlphaCount);
- Array.Clear(areaG, 0, IndexAlphaCount);
- Array.Clear(areaB, 0, IndexAlphaCount);
- Array.Clear(areaA, 0, IndexAlphaCount);
- Array.Clear(area2, 0, IndexAlphaCount);
-
- for (int b = 1; b < IndexCount; b++)
- {
- long line = 0;
- long lineR = 0;
- long lineG = 0;
- long lineB = 0;
- long lineA = 0;
- double line2 = 0;
-
- for (int a = 1; a < IndexAlphaCount; a++)
- {
- int ind1 = GetPaletteIndex(r, g, b, a);
-
- line += this.vwt[ind1];
- lineR += this.vmr[ind1];
- lineG += this.vmg[ind1];
- lineB += this.vmb[ind1];
- lineA += this.vma[ind1];
- line2 += this.m2[ind1];
-
- area[a] += line;
- areaR[a] += lineR;
- areaG[a] += lineG;
- areaB[a] += lineB;
- areaA[a] += lineA;
- area2[a] += line2;
-
- int inv = (b * IndexAlphaCount) + a;
-
- volume[inv] += area[a];
- volumeR[inv] += areaR[a];
- volumeG[inv] += areaG[a];
- volumeB[inv] += areaB[a];
- volumeA[inv] += areaA[a];
- volume2[inv] += area2[a];
-
- int ind2 = ind1 - GetPaletteIndex(1, 0, 0, 0);
-
- this.vwt[ind1] = this.vwt[ind2] + volume[inv];
- this.vmr[ind1] = this.vmr[ind2] + volumeR[inv];
- this.vmg[ind1] = this.vmg[ind2] + volumeG[inv];
- this.vmb[ind1] = this.vmb[ind2] + volumeB[inv];
- this.vma[ind1] = this.vma[ind2] + volumeA[inv];
- this.m2[ind1] = this.m2[ind2] + volume2[inv];
- }
- }
- }
- }
- }
-
- ///
- /// Computes the weighted variance of a box cube.
- ///
- /// The cube.
- /// The .
- private double Variance(Box cube)
- {
- double dr = Volume(cube, this.vmr);
- double dg = Volume(cube, this.vmg);
- double db = Volume(cube, this.vmb);
- double da = Volume(cube, this.vma);
-
- double xx =
- this.m2[GetPaletteIndex(cube.R1, cube.G1, cube.B1, cube.A1)]
- - this.m2[GetPaletteIndex(cube.R1, cube.G1, cube.B1, cube.A0)]
- - this.m2[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A1)]
- + this.m2[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
- - this.m2[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A1)]
- + this.m2[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
- + this.m2[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
- - this.m2[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
- - this.m2[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A1)]
- + this.m2[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
- + this.m2[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
- - this.m2[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
- + this.m2[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
- - this.m2[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
- - this.m2[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
- + this.m2[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
-
- return xx - (((dr * dr) + (dg * dg) + (db * db) + (da * da)) / Volume(cube, this.vwt));
- }
-
- ///
- /// We want to minimize the sum of the variances of two sub-boxes.
- /// The sum(c^2) terms can be ignored since their sum over both sub-boxes
- /// is the same (the sum for the whole box) no matter where we split.
- /// The remaining terms have a minus sign in the variance formula,
- /// so we drop the minus sign and maximize the sum of the two terms.
- ///
- /// The cube.
- /// The direction.
- /// The first position.
- /// The last position.
- /// The cutting point.
- /// The whole red.
- /// The whole green.
- /// The whole blue.
- /// The whole alpha.
- /// The whole weight.
- /// The .
- private double Maximize(Box cube, int direction, int first, int last, out int cut, double wholeR, double wholeG, double wholeB, double wholeA, double wholeW)
- {
- long baseR = Bottom(cube, direction, this.vmr);
- long baseG = Bottom(cube, direction, this.vmg);
- long baseB = Bottom(cube, direction, this.vmb);
- long baseA = Bottom(cube, direction, this.vma);
- long baseW = Bottom(cube, direction, this.vwt);
-
- double max = 0.0;
- cut = -1;
-
- for (int i = first; i < last; i++)
- {
- double halfR = baseR + Top(cube, direction, i, this.vmr);
- double halfG = baseG + Top(cube, direction, i, this.vmg);
- double halfB = baseB + Top(cube, direction, i, this.vmb);
- double halfA = baseA + Top(cube, direction, i, this.vma);
- double halfW = baseW + Top(cube, direction, i, this.vwt);
-
- double temp;
-
- if (Math.Abs(halfW) < Epsilon)
- {
- continue;
- }
-
- temp = ((halfR * halfR) + (halfG * halfG) + (halfB * halfB) + (halfA * halfA)) / halfW;
-
- halfR = wholeR - halfR;
- halfG = wholeG - halfG;
- halfB = wholeB - halfB;
- halfA = wholeA - halfA;
- halfW = wholeW - halfW;
-
- if (Math.Abs(halfW) < Epsilon)
- {
- continue;
- }
-
- temp += ((halfR * halfR) + (halfG * halfG) + (halfB * halfB) + (halfA * halfA)) / halfW;
-
- if (temp > max)
- {
- max = temp;
- cut = i;
- }
- }
-
- return max;
- }
-
- ///
- /// Cuts a box.
- ///
- /// The first set.
- /// The second set.
- /// Returns a value indicating whether the box has been split.
- private bool Cut(Box set1, Box set2)
- {
- double wholeR = Volume(set1, this.vmr);
- double wholeG = Volume(set1, this.vmg);
- double wholeB = Volume(set1, this.vmb);
- double wholeA = Volume(set1, this.vma);
- double wholeW = Volume(set1, this.vwt);
-
- int cutr;
- int cutg;
- int cutb;
- int cuta;
-
- double maxr = this.Maximize(set1, 0, set1.R0 + 1, set1.R1, out cutr, wholeR, wholeG, wholeB, wholeA, wholeW);
- double maxg = this.Maximize(set1, 1, set1.G0 + 1, set1.G1, out cutg, wholeR, wholeG, wholeB, wholeA, wholeW);
- double maxb = this.Maximize(set1, 2, set1.B0 + 1, set1.B1, out cutb, wholeR, wholeG, wholeB, wholeA, wholeW);
- double maxa = this.Maximize(set1, 3, set1.A0 + 1, set1.A1, out cuta, wholeR, wholeG, wholeB, wholeA, wholeW);
-
- int dir;
-
- if ((maxr >= maxg) && (maxr >= maxb) && (maxr >= maxa))
- {
- dir = 0;
-
- if (cutr < 0)
- {
- return false;
- }
- }
- else if ((maxg >= maxr) && (maxg >= maxb) && (maxg >= maxa))
- {
- dir = 1;
- }
- else if ((maxb >= maxr) && (maxb >= maxg) && (maxb >= maxa))
- {
- dir = 2;
- }
- else
- {
- dir = 3;
- }
-
- set2.R1 = set1.R1;
- set2.G1 = set1.G1;
- set2.B1 = set1.B1;
- set2.A1 = set1.A1;
-
- switch (dir)
- {
- // Red
- case 0:
- set2.R0 = set1.R1 = cutr;
- set2.G0 = set1.G0;
- set2.B0 = set1.B0;
- set2.A0 = set1.A0;
- break;
-
- // Green
- case 1:
- set2.G0 = set1.G1 = cutg;
- set2.R0 = set1.R0;
- set2.B0 = set1.B0;
- set2.A0 = set1.A0;
- break;
-
- // Blue
- case 2:
- set2.B0 = set1.B1 = cutb;
- set2.R0 = set1.R0;
- set2.G0 = set1.G0;
- set2.A0 = set1.A0;
- break;
-
- // Alpha
- case 3:
- set2.A0 = set1.A1 = cuta;
- set2.R0 = set1.R0;
- set2.G0 = set1.G0;
- set2.B0 = set1.B0;
- break;
- }
-
- set1.Volume = (set1.R1 - set1.R0) * (set1.G1 - set1.G0) * (set1.B1 - set1.B0) * (set1.A1 - set1.A0);
- set2.Volume = (set2.R1 - set2.R0) * (set2.G1 - set2.G0) * (set2.B1 - set2.B0) * (set2.A1 - set2.A0);
-
- return true;
- }
-
- ///
- /// Marks a color space tag.
- ///
- /// The cube.
- /// A label.
- private void Mark(Box cube, byte label)
- {
- for (int r = cube.R0 + 1; r <= cube.R1; r++)
- {
- for (int g = cube.G0 + 1; g <= cube.G1; g++)
- {
- for (int b = cube.B0 + 1; b <= cube.B1; b++)
- {
- for (int a = cube.A0 + 1; a <= cube.A1; a++)
- {
- this.tag[GetPaletteIndex(r, g, b, a)] = label;
- }
- }
- }
- }
- }
-
- ///
- /// Builds the cube.
- ///
- /// The cube.
- /// The color count.
- private void BuildCube(out Box[] cube, ref int colorCount)
- {
- cube = new Box[colorCount];
- double[] vv = new double[colorCount];
-
- for (int i = 0; i < colorCount; i++)
- {
- cube[i] = new Box();
- }
-
- cube[0].R0 = cube[0].G0 = cube[0].B0 = cube[0].A0 = 0;
- cube[0].R1 = cube[0].G1 = cube[0].B1 = IndexCount - 1;
- cube[0].A1 = IndexAlphaCount - 1;
-
- int next = 0;
-
- for (int i = 1; i < colorCount; i++)
- {
- if (this.Cut(cube[next], cube[i]))
- {
- vv[next] = cube[next].Volume > 1 ? this.Variance(cube[next]) : 0.0;
- vv[i] = cube[i].Volume > 1 ? this.Variance(cube[i]) : 0.0;
- }
- else
- {
- vv[next] = 0.0;
- i--;
- }
-
- next = 0;
-
- double temp = vv[0];
- for (int k = 1; k <= i; k++)
- {
- if (vv[k] > temp)
- {
- temp = vv[k];
- next = k;
- }
- }
-
- if (temp <= 0.0)
- {
- colorCount = i + 1;
- break;
- }
- }
- }
-
- ///
- /// Generates the quantized result.
- ///
- /// The image pixels.
- /// The color count.
- /// The cube.
- /// The result.
- private QuantizedImage GenerateResult(PixelAccessor imagePixels, int colorCount, Box[] cube)
- {
- List pallette = new List();
- byte[] pixels = new byte[imagePixels.Width * imagePixels.Height];
- int transparentIndex = -1;
- int width = imagePixels.Width;
- int height = imagePixels.Height;
-
- for (int k = 0; k < colorCount; k++)
- {
- this.Mark(cube[k], (byte)k);
-
- double weight = Volume(cube[k], this.vwt);
-
- if (Math.Abs(weight) > Epsilon)
- {
- byte r = (byte)(Volume(cube[k], this.vmr) / weight);
- byte g = (byte)(Volume(cube[k], this.vmg) / weight);
- byte b = (byte)(Volume(cube[k], this.vmb) / weight);
- byte a = (byte)(Volume(cube[k], this.vma) / weight);
-
- Bgra32 color = new Bgra32(b, g, r, a);
-
- if (color == Bgra32.Empty)
- {
- transparentIndex = k;
- }
-
- pallette.Add(color);
- }
- else
- {
- pallette.Add(Bgra32.Empty);
- transparentIndex = k;
- }
- }
-
- Parallel.For(
- 0,
- height,
- y =>
- {
- for (int x = 0; x < width; x++)
- {
- Bgra32 color = imagePixels[x, y];
- int a = color.A >> (8 - IndexAlphaBits);
- int r = color.R >> (8 - IndexBits);
- int g = color.G >> (8 - IndexBits);
- int b = color.B >> (8 - IndexBits);
-
- if (transparentIndex > -1 && color.A <= this.Threshold)
- {
- pixels[(y * width) + x] = (byte)transparentIndex;
- continue;
- }
-
- int ind = GetPaletteIndex(r + 1, g + 1, b + 1, a + 1);
- pixels[(y * width) + x] = this.tag[ind];
- }
- });
-
-
- return new QuantizedImage(width, height, pallette.ToArray(), pixels, transparentIndex);
- }
- }
-}
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/Samplers/Crop.cs b/src/ImageProcessorCore - Copy/Samplers/Crop.cs
deleted file mode 100644
index 239fd63f14..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Crop.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Crops an image to the given width and height.
- ///
- /// The image to resize.
- /// The target image width.
- /// The target image height.
- /// A delegate which is called as progress is made processing the image.
- /// The
- public static Image Crop(this Image source, int width, int height, ProgressEventHandler progressHandler = null)
- {
- return Crop(source, width, height, source.Bounds, progressHandler);
- }
-
- ///
- /// Crops an image to the given width and height with the given source rectangle.
- ///
- /// If the source rectangle is smaller than the target dimensions then the
- /// area within the source is resized performing a zoomed crop.
- ///
- ///
- /// The image to crop.
- /// The target image width.
- /// The target image height.
- ///
- /// The structure that specifies the portion of the image object to draw.
- ///
- /// A delegate which is called as progress is made processing the image.
- /// The
- public static Image Crop(this Image source, int width, int height, Rectangle sourceRectangle, ProgressEventHandler progressHandler = null)
- {
- Guard.MustBeGreaterThan(width, 0, nameof(width));
- Guard.MustBeGreaterThan(height, 0, nameof(height));
-
- if (sourceRectangle.Width < width || sourceRectangle.Height < height)
- {
- // If the source rectangle is smaller than the target perform a
- // cropped zoom.
- source = source.Resize(sourceRectangle.Width, sourceRectangle.Height);
- }
-
- CropProcessor processor = new CropProcessor();
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(width, height, sourceRectangle, new Rectangle(0, 0, width, height), processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/EntropyCrop.cs b/src/ImageProcessorCore - Copy/Samplers/EntropyCrop.cs
deleted file mode 100644
index 55284668ca..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/EntropyCrop.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Crops an image to the area of greatest entropy.
- ///
- /// The image to crop.
- /// The threshold for entropic density.
- /// A delegate which is called as progress is made processing the image.
- /// The
- public static Image EntropyCrop(this Image source, float threshold = .5f, ProgressEventHandler progressHandler = null)
- {
- EntropyCropProcessor processor = new EntropyCropProcessor(threshold);
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(source.Width, source.Height, source.Bounds, Rectangle.Empty, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Options/AnchorPosition.cs b/src/ImageProcessorCore - Copy/Samplers/Options/AnchorPosition.cs
deleted file mode 100644
index af840b292a..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Options/AnchorPosition.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// Enumerated anchor positions to apply to resized images.
- ///
- public enum AnchorPosition
- {
- ///
- /// Anchors the position of the image to the center of it's bounding container.
- ///
- Center,
-
- ///
- /// Anchors the position of the image to the top of it's bounding container.
- ///
- Top,
-
- ///
- /// Anchors the position of the image to the bottom of it's bounding container.
- ///
- Bottom,
-
- ///
- /// Anchors the position of the image to the left of it's bounding container.
- ///
- Left,
-
- ///
- /// Anchors the position of the image to the right of it's bounding container.
- ///
- Right,
-
- ///
- /// Anchors the position of the image to the top left side of it's bounding container.
- ///
- TopLeft,
-
- ///
- /// Anchors the position of the image to the top right side of it's bounding container.
- ///
- TopRight,
-
- ///
- /// Anchors the position of the image to the bottom right side of it's bounding container.
- ///
- BottomRight,
-
- ///
- /// Anchors the position of the image to the bottom left side of it's bounding container.
- ///
- BottomLeft
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Options/FlipType.cs b/src/ImageProcessorCore - Copy/Samplers/Options/FlipType.cs
deleted file mode 100644
index c9b21a37e5..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Options/FlipType.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// Provides enumeration over how a image should be flipped.
- ///
- public enum FlipType
- {
- ///
- /// Don't flip the image.
- ///
- None,
-
- ///
- /// Flip the image horizontally.
- ///
- Horizontal,
-
- ///
- /// Flip the image vertically.
- ///
- Vertical,
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Options/ResizeHelper.cs b/src/ImageProcessorCore - Copy/Samplers/Options/ResizeHelper.cs
deleted file mode 100644
index a80ea47778..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Options/ResizeHelper.cs
+++ /dev/null
@@ -1,430 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
- using System.Linq;
-
- ///
- /// Provides methods to help calculate the target rectangle when resizing using the
- /// enumeration.
- ///
- internal static class ResizeHelper
- {
- ///
- /// Calculates the target location and bounds to perform the resize operation against.
- ///
- /// The source image.
- /// The resize options.
- ///
- /// The .
- ///
- public static Rectangle CalculateTargetLocationAndBounds(ImageBase source, ResizeOptions options)
- {
- switch (options.Mode)
- {
- case ResizeMode.Crop:
- return CalculateCropRectangle(source, options);
- case ResizeMode.Pad:
- return CalculatePadRectangle(source, options);
- case ResizeMode.BoxPad:
- return CalculateBoxPadRectangle(source, options);
- case ResizeMode.Max:
- return CalculateMaxRectangle(source, options);
- case ResizeMode.Min:
- return CalculateMinRectangle(source, options);
-
- // Last case ResizeMode.Stretch:
- default:
- return CalculateStretchRectangle(source, options);
- }
- }
-
- ///
- /// Calculates the target rectangle for crop mode.
- ///
- /// The source image.
- /// The resize options.
- ///
- /// The .
- ///
- private static Rectangle CalculateCropRectangle(ImageBase source, ResizeOptions options)
- {
- int width = options.Size.Width;
- int height = options.Size.Height;
-
- if (width <= 0 || height <= 0)
- {
- return new Rectangle(0, 0, source.Width, source.Height);
- }
-
- double ratio;
- int sourceWidth = source.Width;
- int sourceHeight = source.Height;
-
- int destinationX = 0;
- int destinationY = 0;
- int destinationWidth = width;
- int destinationHeight = height;
-
- // Fractional variants for preserving aspect ratio.
- double percentHeight = Math.Abs(height / (double)sourceHeight);
- double percentWidth = Math.Abs(width / (double)sourceWidth);
-
- if (percentHeight < percentWidth)
- {
- ratio = percentWidth;
-
- if (options.CenterCoordinates.Any())
- {
- double center = -(ratio * sourceHeight) * options.CenterCoordinates.First();
- destinationY = (int)center + (height / 2);
-
- if (destinationY > 0)
- {
- destinationY = 0;
- }
-
- if (destinationY < (int)(height - (sourceHeight * ratio)))
- {
- destinationY = (int)(height - (sourceHeight * ratio));
- }
- }
- else
- {
- switch (options.Position)
- {
- case AnchorPosition.Top:
- case AnchorPosition.TopLeft:
- case AnchorPosition.TopRight:
- destinationY = 0;
- break;
- case AnchorPosition.Bottom:
- case AnchorPosition.BottomLeft:
- case AnchorPosition.BottomRight:
- destinationY = (int)(height - (sourceHeight * ratio));
- break;
- default:
- destinationY = (int)((height - (sourceHeight * ratio)) / 2);
- break;
- }
- }
-
- destinationHeight = (int)Math.Ceiling(sourceHeight * percentWidth);
- }
- else
- {
- ratio = percentHeight;
-
- if (options.CenterCoordinates.Any())
- {
- double center = -(ratio * sourceWidth) * options.CenterCoordinates.ToArray()[1];
- destinationX = (int)center + (width / 2);
-
- if (destinationX > 0)
- {
- destinationX = 0;
- }
-
- if (destinationX < (int)(width - (sourceWidth * ratio)))
- {
- destinationX = (int)(width - (sourceWidth * ratio));
- }
- }
- else
- {
- switch (options.Position)
- {
- case AnchorPosition.Left:
- case AnchorPosition.TopLeft:
- case AnchorPosition.BottomLeft:
- destinationX = 0;
- break;
- case AnchorPosition.Right:
- case AnchorPosition.TopRight:
- case AnchorPosition.BottomRight:
- destinationX = (int)(width - (sourceWidth * ratio));
- break;
- default:
- destinationX = (int)((width - (sourceWidth * ratio)) / 2);
- break;
- }
- }
-
- destinationWidth = (int)Math.Ceiling(sourceWidth * percentHeight);
- }
-
- return new Rectangle(destinationX, destinationY, destinationWidth, destinationHeight);
- }
-
- ///
- /// Calculates the target rectangle for pad mode.
- ///
- /// The source image.
- /// The resize options.
- ///
- /// The .
- ///
- private static Rectangle CalculatePadRectangle(ImageBase source, ResizeOptions options)
- {
- int width = options.Size.Width;
- int height = options.Size.Height;
-
- if (width <= 0 || height <= 0)
- {
- return new Rectangle(0, 0, source.Width, source.Height);
- }
-
- double ratio;
- int sourceWidth = source.Width;
- int sourceHeight = source.Height;
-
- int destinationX = 0;
- int destinationY = 0;
- int destinationWidth = width;
- int destinationHeight = height;
-
- // Fractional variants for preserving aspect ratio.
- double percentHeight = Math.Abs(height / (double)sourceHeight);
- double percentWidth = Math.Abs(width / (double)sourceWidth);
-
- if (percentHeight < percentWidth)
- {
- ratio = percentHeight;
- destinationWidth = Convert.ToInt32(sourceWidth * percentHeight);
-
- switch (options.Position)
- {
- case AnchorPosition.Left:
- case AnchorPosition.TopLeft:
- case AnchorPosition.BottomLeft:
- destinationX = 0;
- break;
- case AnchorPosition.Right:
- case AnchorPosition.TopRight:
- case AnchorPosition.BottomRight:
- destinationX = (int)(width - (sourceWidth * ratio));
- break;
- default:
- destinationX = Convert.ToInt32((width - (sourceWidth * ratio)) / 2);
- break;
- }
- }
- else
- {
- ratio = percentWidth;
- destinationHeight = Convert.ToInt32(sourceHeight * percentWidth);
-
- switch (options.Position)
- {
- case AnchorPosition.Top:
- case AnchorPosition.TopLeft:
- case AnchorPosition.TopRight:
- destinationY = 0;
- break;
- case AnchorPosition.Bottom:
- case AnchorPosition.BottomLeft:
- case AnchorPosition.BottomRight:
- destinationY = (int)(height - (sourceHeight * ratio));
- break;
- default:
- destinationY = (int)((height - (sourceHeight * ratio)) / 2);
- break;
- }
- }
-
- return new Rectangle(destinationX, destinationY, destinationWidth, destinationHeight);
- }
-
- ///
- /// Calculates the target rectangle for box pad mode.
- ///
- /// The source image.
- /// The resize options.
- ///
- /// The .
- ///
- private static Rectangle CalculateBoxPadRectangle(ImageBase source, ResizeOptions options)
- {
- int width = options.Size.Width;
- int height = options.Size.Height;
-
- if (width <= 0 || height <= 0)
- {
- return new Rectangle(0, 0, source.Width, source.Height);
- }
-
- int sourceWidth = source.Width;
- int sourceHeight = source.Height;
-
- // Fractional variants for preserving aspect ratio.
- double percentHeight = Math.Abs(height / (double)sourceHeight);
- double percentWidth = Math.Abs(width / (double)sourceWidth);
-
- int boxPadHeight = height > 0 ? height : Convert.ToInt32(sourceHeight * percentWidth);
- int boxPadWidth = width > 0 ? width : Convert.ToInt32(sourceWidth * percentHeight);
-
- // Only calculate if upscaling.
- if (sourceWidth < boxPadWidth && sourceHeight < boxPadHeight)
- {
- int destinationX;
- int destinationY;
- int destinationWidth = sourceWidth;
- int destinationHeight = sourceHeight;
- width = boxPadWidth;
- height = boxPadHeight;
-
- switch (options.Position)
- {
- case AnchorPosition.Left:
- destinationY = (height - sourceHeight) / 2;
- destinationX = 0;
- break;
- case AnchorPosition.Right:
- destinationY = (height - sourceHeight) / 2;
- destinationX = width - sourceWidth;
- break;
- case AnchorPosition.TopRight:
- destinationY = 0;
- destinationX = width - sourceWidth;
- break;
- case AnchorPosition.Top:
- destinationY = 0;
- destinationX = (width - sourceWidth) / 2;
- break;
- case AnchorPosition.TopLeft:
- destinationY = 0;
- destinationX = 0;
- break;
- case AnchorPosition.BottomRight:
- destinationY = height - sourceHeight;
- destinationX = width - sourceWidth;
- break;
- case AnchorPosition.Bottom:
- destinationY = height - sourceHeight;
- destinationX = (width - sourceWidth) / 2;
- break;
- case AnchorPosition.BottomLeft:
- destinationY = height - sourceHeight;
- destinationX = 0;
- break;
- default:
- destinationY = (height - sourceHeight) / 2;
- destinationX = (width - sourceWidth) / 2;
- break;
- }
-
- return new Rectangle(destinationX, destinationY, destinationWidth, destinationHeight);
- }
-
- // Switch to pad mode to downscale and calculate from there.
- return CalculatePadRectangle(source, options);
- }
-
- ///
- /// Calculates the target rectangle for max mode.
- ///
- /// The source image.
- /// The resize options.
- ///
- /// The .
- ///
- private static Rectangle CalculateMaxRectangle(ImageBase source, ResizeOptions options)
- {
- int width = options.Size.Width;
- int height = options.Size.Height;
- int destinationWidth = width;
- int destinationHeight = height;
-
- // Fractional variants for preserving aspect ratio.
- double percentHeight = Math.Abs(height / (double)source.Height);
- double percentWidth = Math.Abs(width / (double)source.Width);
-
- // Integers must be cast to doubles to get needed precision
- double ratio = (double)options.Size.Height / options.Size.Width;
- double sourceRatio = (double)source.Height / source.Width;
-
- if (sourceRatio < ratio)
- {
- destinationHeight = Convert.ToInt32(source.Height * percentWidth);
- height = destinationHeight;
- }
- else
- {
- destinationWidth = Convert.ToInt32(source.Width * percentHeight);
- width = destinationWidth;
- }
-
- // Replace the size to match the rectangle.
- options.Size = new Size(width, height);
- return new Rectangle(0, 0, destinationWidth, destinationHeight);
- }
-
- ///
- /// Calculates the target rectangle for min mode.
- ///
- /// The source image.
- /// The resize options.
- ///
- /// The .
- ///
- private static Rectangle CalculateMinRectangle(ImageBase source, ResizeOptions options)
- {
- int width = options.Size.Width;
- int height = options.Size.Height;
- int destinationWidth;
- int destinationHeight;
-
- // Don't upscale
- if (width > source.Width || height > source.Height)
- {
- options.Size = new Size(source.Width, source.Height);
- return new Rectangle(0, 0, source.Width, source.Height);
- }
-
- double sourceRatio = (double)source.Height / source.Width;
-
- // Find the shortest distance to go.
- int widthDiff = source.Width - width;
- int heightDiff = source.Height - height;
-
- if (widthDiff < heightDiff)
- {
- destinationHeight = Convert.ToInt32(width * sourceRatio);
- height = destinationHeight;
- destinationWidth = width;
- }
- else if (widthDiff > heightDiff)
- {
- destinationWidth = Convert.ToInt32(height / sourceRatio);
- destinationHeight = height;
- width = destinationWidth;
- }
- else
- {
- destinationWidth = width;
- destinationHeight = height;
- }
-
- // Replace the size to match the rectangle.
- options.Size = new Size(width, height);
- return new Rectangle(0, 0, destinationWidth, destinationHeight);
- }
-
- ///
- /// Calculates the target rectangle for stretch mode.
- ///
- /// The source image.
- /// The resize options.
- ///
- /// The .
- ///
- private static Rectangle CalculateStretchRectangle(ImageBase source, ResizeOptions options)
- {
- return new Rectangle(0, 0, options.Size.Width, options.Size.Height);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Options/ResizeMode.cs b/src/ImageProcessorCore - Copy/Samplers/Options/ResizeMode.cs
deleted file mode 100644
index a0ce943417..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Options/ResizeMode.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// Enumerated resize modes to apply to resized images.
- ///
- public enum ResizeMode
- {
- ///
- /// Crops the resized image to fit the bounds of its container.
- ///
- Crop,
-
- ///
- /// Pads the resized image to fit the bounds of its container.
- /// If only one dimension is passed, will maintain the original aspect ratio.
- ///
- Pad,
-
- ///
- /// Pads the image to fit the bound of the container without resizing the
- /// original source.
- /// When downscaling, performs the same functionality as
- ///
- BoxPad,
-
- ///
- /// Constrains the resized image to fit the bounds of its container maintaining
- /// the original aspect ratio.
- ///
- Max,
-
- ///
- /// Resizes the image until the shortest side reaches the set given dimension.
- /// Upscaling is disabled in this mode and the original image will be returned
- /// if attempted.
- ///
- Min,
-
- ///
- /// Stretches the resized image to fit the bounds of its container.
- ///
- Stretch
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Options/ResizeOptions.cs b/src/ImageProcessorCore - Copy/Samplers/Options/ResizeOptions.cs
deleted file mode 100644
index 82db8ed860..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Options/ResizeOptions.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System.Collections.Generic;
- using System.Linq;
-
- ///
- /// The resize options for resizing images against certain modes.
- ///
- public class ResizeOptions
- {
- ///
- /// Gets or sets the resize mode.
- ///
- public ResizeMode Mode { get; set; } = ResizeMode.Crop;
-
- ///
- /// Gets or sets the anchor position.
- ///
- public AnchorPosition Position { get; set; } = AnchorPosition.Center;
-
- ///
- /// Gets or sets the center coordinates.
- ///
- public IEnumerable CenterCoordinates { get; set; } = Enumerable.Empty();
-
- ///
- /// Gets or sets the target size.
- ///
- public Size Size { get; set; }
-
- ///
- /// Gets or sets the sampler to perform the resize operation.
- ///
- public IResampler Sampler { get; set; } = new BicubicResampler();
-
- ///
- /// Gets or sets a value indicating whether to compress
- /// or expand individual pixel colors the value on processing.
- ///
- public bool Compand { get; set; }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Options/RotateType.cs b/src/ImageProcessorCore - Copy/Samplers/Options/RotateType.cs
deleted file mode 100644
index 43644de858..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Options/RotateType.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// Provides enumeration over how the image should be rotated.
- ///
- public enum RotateType
- {
- ///
- /// Do not rotate the image.
- ///
- None,
-
- ///
- /// Rotate the image by 90 degrees clockwise.
- ///
- Rotate90,
-
- ///
- /// Rotate the image by 180 degrees clockwise.
- ///
- Rotate180,
-
- ///
- /// Rotate the image by 270 degrees clockwise.
- ///
- Rotate270
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Pad.cs b/src/ImageProcessorCore - Copy/Samplers/Pad.cs
deleted file mode 100644
index de973d3454..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Pad.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Evenly pads an image to fit the new dimensions.
- ///
- /// The source image to pad.
- /// The new width.
- /// The new height.
- /// A delegate which is called as progress is made processing the image.
- /// The .
- public static Image Pad(this Image source, int width, int height, ProgressEventHandler progressHandler = null)
- {
- ResizeOptions options = new ResizeOptions
- {
- Size = new Size(width, height),
- Mode = ResizeMode.BoxPad,
- Sampler = new NearestNeighborResampler()
- };
-
- return Resize(source, options, progressHandler);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Processors/CropProcessor.cs b/src/ImageProcessorCore - Copy/Samplers/Processors/CropProcessor.cs
deleted file mode 100644
index adcd3c180c..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Processors/CropProcessor.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Threading.Tasks;
-
- ///
- /// Provides methods to allow the cropping of an image.
- ///
- public class CropProcessor : ImageSampler
- {
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- int startX = targetRectangle.X;
- int endX = targetRectangle.Right;
- int sourceX = sourceRectangle.X;
- int sourceY = sourceRectangle.Y;
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- startY,
- endY,
- y =>
- {
- for (int x = startX; x < endX; x++)
- {
- targetPixels[x, y] = sourcePixels[x + sourceX, y + sourceY];
- }
-
- this.OnRowProcessed();
- });
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Processors/EntropyCropProcessor.cs b/src/ImageProcessorCore - Copy/Samplers/Processors/EntropyCropProcessor.cs
deleted file mode 100644
index f9f8601f52..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Processors/EntropyCropProcessor.cs
+++ /dev/null
@@ -1,104 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System;
- using System.Threading.Tasks;
-
- ///
- /// Provides methods to allow the cropping of an image to preserve areas of highest
- /// entropy.
- ///
- public class EntropyCropProcessor : ImageSampler
- {
- ///
- /// The rectangle for cropping
- ///
- private Rectangle cropRectangle;
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The threshold to split the image. Must be between 0 and 1.
- ///
- /// is less than 0 or is greater than 1.
- ///
- public EntropyCropProcessor(float threshold)
- {
- Guard.MustBeBetweenOrEqualTo(threshold, 0, 1, nameof(threshold));
- this.Value = threshold;
- }
-
- ///
- /// Gets the threshold value.
- ///
- public float Value { get; }
-
- ///
- protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
- {
- ImageBase temp = new Image(source.Width, source.Height);
-
- // Detect the edges.
- new SobelProcessor().Apply(temp, source, sourceRectangle);
-
- // Apply threshold binarization filter.
- new ThresholdProcessor(.5f).Apply(temp, temp, sourceRectangle);
-
- // Search for the first white pixels
- Rectangle rectangle = ImageMaths.GetFilteredBoundingRectangle(temp, 0);
-
- // Reset the target pixel to the correct size.
- target.SetPixels(rectangle.Width, rectangle.Height, new float[rectangle.Width * rectangle.Height * 4]);
- this.cropRectangle = rectangle;
- }
-
- ///
- 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)
- {
- return;
- }
-
- int targetY = this.cropRectangle.Y;
- int targetBottom = this.cropRectangle.Bottom;
- int startX = this.cropRectangle.X;
- int endX = this.cropRectangle.Right;
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- startY,
- endY,
- y =>
- {
- if (y >= targetY && y < targetBottom)
- {
- for (int x = startX; x < endX; x++)
- {
- targetPixels[x - startX, y - targetY] = sourcePixels[x, y];
- }
- }
-
- this.OnRowProcessed();
- });
- }
- }
-
- ///
- protected override void AfterApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
- {
- // Copy the pixels over.
- if (source.Bounds == target.Bounds)
- {
- target.ClonePixels(target.Width, target.Height, source.Pixels);
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Processors/IImageSampler.cs b/src/ImageProcessorCore - Copy/Samplers/Processors/IImageSampler.cs
deleted file mode 100644
index 76a2c5a4d4..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Processors/IImageSampler.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// Acts as a marker for generic parameters that require an image sampler.
- ///
- public interface IImageSampler : IImageProcessor
- {
- ///
- /// Gets or sets a value indicating whether to compress
- /// or expand individual pixel colors the value on processing.
- ///
- bool Compand { get; set; }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Processors/ImageSampler.cs b/src/ImageProcessorCore - Copy/Samplers/Processors/ImageSampler.cs
deleted file mode 100644
index adfe77432f..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Processors/ImageSampler.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// Applies sampling methods to an image.
- /// All processors requiring resampling or resizing should inherit from this.
- ///
- public abstract class ImageSampler : ImageProcessor, IImageSampler
- {
- ///
- public virtual bool Compand { get; set; } = false;
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Processors/Matrix3x2Processor.cs b/src/ImageProcessorCore - Copy/Samplers/Processors/Matrix3x2Processor.cs
deleted file mode 100644
index e9b0441e3d..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Processors/Matrix3x2Processor.cs
+++ /dev/null
@@ -1,47 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
-
- ///
- /// Provides methods to transform an image using a .
- ///
- public abstract class Matrix3x2Processor : ImageSampler
- {
- ///
- /// Creates a new target to contain the results of the matrix transform.
- ///
- /// Target image to apply the process to.
- /// The source rectangle.
- /// The processing matrix.
- protected static void CreateNewTarget(ImageBase target, Rectangle sourceRectangle, Matrix3x2 processMatrix)
- {
- Matrix3x2 sizeMatrix;
- if (Matrix3x2.Invert(processMatrix, out sizeMatrix))
- {
- Rectangle rectangle = ImageMaths.GetBoundingRectangle(sourceRectangle, sizeMatrix);
- target.SetPixels(rectangle.Width, rectangle.Height, new float[rectangle.Width * rectangle.Height * 4]);
- }
- }
-
- ///
- /// Gets a transform matrix adjusted to center upon the target image bounds.
- ///
- /// Target image to apply the process to.
- /// The source image.
- /// The transform matrix.
- ///
- /// The .
- ///
- protected static Matrix3x2 GetCenteredMatrix(ImageBase target, ImageBase source, Matrix3x2 matrix)
- {
- Matrix3x2 translationToTargetCenter = Matrix3x2.CreateTranslation(-target.Width / 2f, -target.Height / 2f);
- Matrix3x2 translateToSourceCenter = Matrix3x2.CreateTranslation(source.Width / 2f, source.Height / 2f);
- return (translationToTargetCenter * matrix) * translateToSourceCenter;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Processors/ResizeProcessor.cs b/src/ImageProcessorCore - Copy/Samplers/Processors/ResizeProcessor.cs
deleted file mode 100644
index 95ead2bf04..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Processors/ResizeProcessor.cs
+++ /dev/null
@@ -1,362 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System;
- using System.Threading.Tasks;
-
- ///
- /// Provides methods that allow the resizing of images using various algorithms.
- ///
- public class ResizeProcessor : ImageSampler
- {
- ///
- /// The image used for storing the first pass pixels.
- ///
- private Image firstPass;
-
- ///
- /// 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);
- }
-
- this.firstPass = new Image(target.Width, source.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 (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor 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.
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor firstPassPixels = this.firstPass.Lock())
- using (PixelAccessor 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;
- }
- }
- });
-
- // 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
- Color destination = new Color();
-
- for (int i = 0; i < sum; i++)
- {
- Weight yw = verticalValues[i];
- int originY = yw.Index;
- Color sourceColor = compand
- ? Color.Expand(firstPassPixels[x, originY])
- : firstPassPixels[x, originY];
-
- destination += sourceColor * yw.Value;
- }
-
- if (compand)
- {
- destination = Color.Compress(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/src/ImageProcessorCore - Copy/Samplers/Processors/RotateFlipProcessor.cs b/src/ImageProcessorCore - Copy/Samplers/Processors/RotateFlipProcessor.cs
deleted file mode 100644
index 6ef8866ba1..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Processors/RotateFlipProcessor.cs
+++ /dev/null
@@ -1,231 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System;
- using System.Threading.Tasks;
-
- ///
- /// Provides methods that allow the rotation and flipping of an image around its center point.
- ///
- public class RotateFlipProcessor : ImageSampler
- {
- ///
- /// Initializes a new instance of the class.
- ///
- /// The used to perform rotation.
- /// The used to perform flipping.
- public RotateFlipProcessor(RotateType rotateType, FlipType flipType)
- {
- this.RotateType = rotateType;
- this.FlipType = flipType;
- }
-
- ///
- /// Gets the used to perform flipping.
- ///
- public FlipType FlipType { get; }
-
- ///
- /// Gets the used to perform rotation.
- ///
- public RotateType RotateType { get; }
-
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- switch (this.RotateType)
- {
- case RotateType.Rotate90:
- this.Rotate90(target, source);
- break;
- case RotateType.Rotate180:
- this.Rotate180(target, source);
- break;
- case RotateType.Rotate270:
- this.Rotate270(target, source);
- break;
- default:
- target.ClonePixels(target.Width, target.Height, source.Pixels);
- break;
- }
-
- switch (this.FlipType)
- {
- // No default needed as we have already set the pixels.
- case FlipType.Vertical:
- this.FlipX(target);
- break;
- case FlipType.Horizontal:
- this.FlipY(target);
- break;
- }
- }
-
- ///
- /// Rotates the image 270 degrees clockwise at the centre point.
- ///
- /// The target image.
- /// The source image.
- private void Rotate270(ImageBase target, ImageBase source)
- {
- int width = source.Width;
- int height = source.Height;
- Image temp = new Image(height, width);
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor tempPixels = temp.Lock())
- {
- Parallel.For(
- 0,
- height,
- y =>
- {
- for (int x = 0; x < width; x++)
- {
- int newX = height - y - 1;
- newX = height - newX - 1;
- int newY = width - x - 1;
- newY = width - newY - 1;
- tempPixels[newX, newY] = sourcePixels[x, y];
- }
-
- this.OnRowProcessed();
- });
- }
-
- target.SetPixels(height, width, temp.Pixels);
- }
-
- ///
- /// Rotates the image 180 degrees clockwise at the centre point.
- ///
- /// The target image.
- /// The source image.
- private void Rotate180(ImageBase target, ImageBase source)
- {
- int width = source.Width;
- int height = source.Height;
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- 0,
- height,
- y =>
- {
- for (int x = 0; x < width; x++)
- {
- int newX = width - x - 1;
- int newY = height - y - 1;
- targetPixels[newX, newY] = sourcePixels[x, y];
- }
-
- this.OnRowProcessed();
- });
- }
- }
-
- ///
- /// Rotates the image 90 degrees clockwise at the centre point.
- ///
- /// The target image.
- /// The source image.
- private void Rotate90(ImageBase target, ImageBase source)
- {
- int width = source.Width;
- int height = source.Height;
- Image temp = new Image(height, width);
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor tempPixels = temp.Lock())
- {
- Parallel.For(
- 0,
- height,
- y =>
- {
- for (int x = 0; x < width; x++)
- {
- int newX = height - y - 1;
- tempPixels[newX, x] = sourcePixels[x, y];
- }
-
- this.OnRowProcessed();
- });
- }
-
- target.SetPixels(height, width, temp.Pixels);
- }
-
- ///
- /// Swaps the image at the X-axis, which goes horizontally through the middle
- /// at half the height of the image.
- ///
- /// Target image to apply the process to.
- private void FlipX(ImageBase target)
- {
- int width = target.Width;
- int height = target.Height;
- int halfHeight = (int)Math.Ceiling(target.Height * .5);
- ImageBase temp = new Image(width, height);
- temp.ClonePixels(width, height, target.Pixels);
-
- using (PixelAccessor targetPixels = target.Lock())
- using (PixelAccessor tempPixels = temp.Lock())
- {
- Parallel.For(
- 0,
- halfHeight,
- y =>
- {
- for (int x = 0; x < width; x++)
- {
- int newY = height - y - 1;
- targetPixels[x, y] = tempPixels[x, newY];
- targetPixels[x, newY] = tempPixels[x, y];
- }
-
- this.OnRowProcessed();
- });
- }
- }
-
- ///
- /// Swaps the image at the Y-axis, which goes vertically through the middle
- /// at half of the width of the image.
- ///
- /// Target image to apply the process to.
- private void FlipY(ImageBase target)
- {
- int width = target.Width;
- int height = target.Height;
- int halfWidth = (int)Math.Ceiling(width / 2d);
- ImageBase temp = new Image(width, height);
- temp.ClonePixels(width, height, target.Pixels);
-
- using (PixelAccessor targetPixels = target.Lock())
- using (PixelAccessor tempPixels = temp.Lock())
- {
- Parallel.For(
- 0,
- height,
- y =>
- {
- for (int x = 0; x < halfWidth; x++)
- {
- int newX = width - x - 1;
- targetPixels[x, y] = tempPixels[newX, y];
- targetPixels[newX, y] = tempPixels[x, y];
- }
-
- this.OnRowProcessed();
- });
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Processors/RotateProcessor.cs b/src/ImageProcessorCore - Copy/Samplers/Processors/RotateProcessor.cs
deleted file mode 100644
index 7aafe0e082..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Processors/RotateProcessor.cs
+++ /dev/null
@@ -1,68 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
- using System.Threading.Tasks;
-
- ///
- /// Provides methods that allow the rotating of images.
- ///
- public class RotateProcessor : Matrix3x2Processor
- {
- ///
- /// The tranform matrix to apply.
- ///
- private Matrix3x2 processMatrix;
-
- ///
- /// Gets or sets the angle of processMatrix in degrees.
- ///
- public float Angle { get; set; }
-
- ///
- /// Gets or sets a value indicating whether to expand the canvas to fit the rotated image.
- ///
- public bool Expand { get; set; } = true;
-
- ///
- protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
- {
- processMatrix = Point.CreateRotation(new Point(0, 0), -this.Angle);
- if (this.Expand)
- {
- CreateNewTarget(target, sourceRectangle, processMatrix);
- }
- }
-
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- Matrix3x2 matrix = GetCenteredMatrix(target, source, this.processMatrix);
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- 0,
- target.Height,
- y =>
- {
- for (int x = 0; x < target.Width; x++)
- {
- Point transformedPoint = Point.Rotate(new Point(x, y), matrix);
- if (source.Bounds.Contains(transformedPoint.X, transformedPoint.Y))
- {
- targetPixels[x, y] = sourcePixels[transformedPoint.X, transformedPoint.Y];
- }
- }
-
- OnRowProcessed();
- });
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/Samplers/Processors/SkewProcessor.cs b/src/ImageProcessorCore - Copy/Samplers/Processors/SkewProcessor.cs
deleted file mode 100644
index 02d5dd9e44..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Processors/SkewProcessor.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- using System.Numerics;
- using System.Threading.Tasks;
-
- ///
- /// Provides methods that allow the skewing of images.
- ///
- public class SkewProcessor : Matrix3x2Processor
- {
- ///
- /// The tranform matrix to apply.
- ///
- private Matrix3x2 processMatrix;
-
- ///
- /// Gets or sets the angle of rotation along the x-axis in degrees.
- ///
- public float AngleX { get; set; }
-
- ///
- /// Gets or sets the angle of rotation along the y-axis in degrees.
- ///
- public float AngleY { get; set; }
-
- ///
- /// Gets or sets a value indicating whether to expand the canvas to fit the skewed image.
- ///
- public bool Expand { get; set; } = true;
-
- ///
- protected override void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
- {
- this.processMatrix = Point.CreateSkew(new Point(0, 0), -this.AngleX, -this.AngleY);
- if (this.Expand)
- {
- CreateNewTarget(target, sourceRectangle, this.processMatrix);
- }
- }
-
- ///
- protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
- {
- Matrix3x2 matrix = GetCenteredMatrix(target, source, this.processMatrix);
-
- using (PixelAccessor sourcePixels = source.Lock())
- using (PixelAccessor targetPixels = target.Lock())
- {
- Parallel.For(
- 0,
- target.Height,
- y =>
- {
- for (int x = 0; x < target.Width; x++)
- {
- Point transformedPoint = Point.Skew(new Point(x, y), matrix);
- if (source.Bounds.Contains(transformedPoint.X, transformedPoint.Y))
- {
- targetPixels[x, y] = sourcePixels[transformedPoint.X, transformedPoint.Y];
- }
- }
-
- OnRowProcessed();
- });
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resamplers/BicubicResampler.cs b/src/ImageProcessorCore - Copy/Samplers/Resamplers/BicubicResampler.cs
deleted file mode 100644
index 8aecac7a60..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resamplers/BicubicResampler.cs
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// The function implements the bicubic kernel algorithm W(x) as described on
- /// Wikipedia
- /// A commonly used algorithm within imageprocessing that preserves sharpness better than triangle interpolation.
- ///
- public class BicubicResampler : IResampler
- {
- ///
- public float Radius => 2;
-
- ///
- public float GetValue(float x)
- {
- // The coefficient.
- float a = -0.5f;
-
- if (x < 0)
- {
- x = -x;
- }
-
- float result = 0;
-
- if (x <= 1)
- {
- result = (((1.5f * x) - 2.5f) * x * x) + 1;
- }
- else if (x < 2)
- {
- result = (((((a * x) + 2.5f) * x) - 4) * x) + 2;
- }
-
- return result;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resamplers/BoxResampler.cs b/src/ImageProcessorCore - Copy/Samplers/Resamplers/BoxResampler.cs
deleted file mode 100644
index b1234e415d..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resamplers/BoxResampler.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// The function implements the box algorithm. Similar to nearest neighbour when upscaling.
- /// When downscaling the pixels will average, merging together.
- ///
- public class BoxResampler : IResampler
- {
- ///
- public float Radius => 0.5F;
-
- ///
- public float GetValue(float x)
- {
- if (x > -0.5 && x <= 0.5)
- {
- return 1;
- }
-
- return 0;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resamplers/CatmullRomResampler.cs b/src/ImageProcessorCore - Copy/Samplers/Resamplers/CatmullRomResampler.cs
deleted file mode 100644
index 0b5031df88..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resamplers/CatmullRomResampler.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// The Catmull-Rom filter is a well known standard Cubic Filter often used as a interpolation function.
- /// This filter produces a reasonably sharp edge, but without a the pronounced gradient change on large
- /// scale image enlargements that a 'Lagrange' filter can produce.
- ///
- ///
- public class CatmullRomResampler : IResampler
- {
- ///
- public float Radius => 2;
-
- ///
- public float GetValue(float x)
- {
- const float B = 0;
- const float C = 1 / 2f;
-
- return ImageMaths.GetBcValue(x, B, C);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resamplers/HermiteResampler.cs b/src/ImageProcessorCore - Copy/Samplers/Resamplers/HermiteResampler.cs
deleted file mode 100644
index 49193a3de3..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resamplers/HermiteResampler.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore.Processors
-{
- ///
- /// The Hermite filter is type of smoothed triangular interpolation Filter,
- /// This filter rounds off strong edges while preserving flat 'color levels' in the original image.
- ///
- ///
- public class HermiteResampler : IResampler
- {
- ///
- public float Radius => 2;
-
- ///
- public float GetValue(float x)
- {
- const float B = 0;
- const float C = 0;
-
- return ImageMaths.GetBcValue(x, B, C);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resamplers/IResampler.cs b/src/ImageProcessorCore - Copy/Samplers/Resamplers/IResampler.cs
deleted file mode 100644
index 0dea58440c..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resamplers/IResampler.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// Encapsulates an interpolation algorithm for resampling images.
- ///
- public interface IResampler
- {
- ///
- /// Gets the radius in which to sample pixels.
- ///
- float Radius { get; }
-
- ///
- /// Gets the result of the interpolation algorithm.
- ///
- /// The value to process.
- ///
- /// The
- ///
- float GetValue(float x);
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resamplers/Lanczos3Resampler.cs b/src/ImageProcessorCore - Copy/Samplers/Resamplers/Lanczos3Resampler.cs
deleted file mode 100644
index a78b6c066a..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resamplers/Lanczos3Resampler.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// The function implements the Lanczos kernel algorithm as described on
- /// Wikipedia
- /// with a radius of 3 pixels.
- ///
- public class Lanczos3Resampler : IResampler
- {
- ///
- public float Radius => 3;
-
- ///
- public float GetValue(float x)
- {
- if (x < 0)
- {
- x = -x;
- }
-
- if (x < 3)
- {
- return ImageMaths.SinC(x) * ImageMaths.SinC(x / 3f);
- }
-
- return 0;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resamplers/Lanczos5Resampler.cs b/src/ImageProcessorCore - Copy/Samplers/Resamplers/Lanczos5Resampler.cs
deleted file mode 100644
index 05af2dd7f2..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resamplers/Lanczos5Resampler.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// The function implements the Lanczos kernel algorithm as described on
- /// Wikipedia
- /// with a radius of 5 pixels.
- ///
- public class Lanczos5Resampler : IResampler
- {
- ///
- public float Radius => 5;
-
- ///
- public float GetValue(float x)
- {
- if (x < 0)
- {
- x = -x;
- }
-
- if (x < 5)
- {
- return ImageMaths.SinC(x) * ImageMaths.SinC(x / 5f);
- }
-
- return 0;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resamplers/Lanczos8Resampler.cs b/src/ImageProcessorCore - Copy/Samplers/Resamplers/Lanczos8Resampler.cs
deleted file mode 100644
index 8c9a9237d9..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resamplers/Lanczos8Resampler.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// The function implements the Lanczos kernel algorithm as described on
- /// Wikipedia
- /// with a radius of 8 pixels.
- ///
- public class Lanczos8Resampler : IResampler
- {
- ///
- public float Radius => 8;
-
- ///
- public float GetValue(float x)
- {
- if (x < 0)
- {
- x = -x;
- }
-
- if (x < 8)
- {
- return ImageMaths.SinC(x) * ImageMaths.SinC(x / 8f);
- }
-
- return 0;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resamplers/MitchellNetravaliResampler.cs b/src/ImageProcessorCore - Copy/Samplers/Resamplers/MitchellNetravaliResampler.cs
deleted file mode 100644
index f609f26450..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resamplers/MitchellNetravaliResampler.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// The function implements the mitchell algorithm as described on
- /// Wikipedia
- ///
- public class MitchellNetravaliResampler : IResampler
- {
- ///
- public float Radius => 2;
-
- ///
- public float GetValue(float x)
- {
- const float B = 1 / 3f;
- const float C = 1 / 3f;
-
- return ImageMaths.GetBcValue(x, B, C);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resamplers/NearestNeighborResampler.cs b/src/ImageProcessorCore - Copy/Samplers/Resamplers/NearestNeighborResampler.cs
deleted file mode 100644
index 58b6a9d584..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resamplers/NearestNeighborResampler.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// The function implements the nearest neighbour algorithm. This uses an unscaled filter
- /// which will select the closest pixel to the new pixels position.
- ///
- public class NearestNeighborResampler : IResampler
- {
- ///
- public float Radius => 1;
-
- ///
- public float GetValue(float x)
- {
- return x;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resamplers/RobidouxResampler.cs b/src/ImageProcessorCore - Copy/Samplers/Resamplers/RobidouxResampler.cs
deleted file mode 100644
index caead12d5d..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resamplers/RobidouxResampler.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// The function implements the Robidoux algorithm.
- ///
- ///
- public class RobidouxResampler : IResampler
- {
- ///
- public float Radius => 2;
-
- ///
- public float GetValue(float x)
- {
- const float B = 0.3782158F;
- const float C = 0.3108921F;
-
- return ImageMaths.GetBcValue(x, B, C);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resamplers/RobidouxSharpResampler.cs b/src/ImageProcessorCore - Copy/Samplers/Resamplers/RobidouxSharpResampler.cs
deleted file mode 100644
index 633503cd16..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resamplers/RobidouxSharpResampler.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// The function implements the Robidoux Sharp algorithm.
- ///
- ///
- public class RobidouxSharpResampler : IResampler
- {
- ///
- public float Radius => 2;
-
- ///
- public float GetValue(float x)
- {
- const float B = 0.26201451F;
- const float C = 0.36899274F;
-
- return ImageMaths.GetBcValue(x, B, C);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resamplers/RobidouxSoftResampler.cs b/src/ImageProcessorCore - Copy/Samplers/Resamplers/RobidouxSoftResampler.cs
deleted file mode 100644
index 8706f492bb..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resamplers/RobidouxSoftResampler.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// The function implements the Robidoux Soft algorithm.
- ///
- ///
- public class RobidouxSoftResampler : IResampler
- {
- ///
- public float Radius => 2;
-
- ///
- public float GetValue(float x)
- {
- const float B = 0.6796f;
- const float C = 0.1602f;
-
- return ImageMaths.GetBcValue(x, B, C);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resamplers/SplineResampler.cs b/src/ImageProcessorCore - Copy/Samplers/Resamplers/SplineResampler.cs
deleted file mode 100644
index 55ef5656a9..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resamplers/SplineResampler.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// The function implements the spline algorithm.
- ///
- ///
- public class SplineResampler : IResampler
- {
- ///
- public float Radius => 2;
-
- ///
- public float GetValue(float x)
- {
- const float B = 1;
- const float C = 0;
-
- return ImageMaths.GetBcValue(x, B, C);
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resamplers/TriangleResampler.cs b/src/ImageProcessorCore - Copy/Samplers/Resamplers/TriangleResampler.cs
deleted file mode 100644
index cb404b7369..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resamplers/TriangleResampler.cs
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// The function implements the triangle (bilinear) algorithm.
- /// Bilinear interpolation can be used where perfect image transformation with pixel matching is impossible,
- /// so that one can calculate and assign appropriate intensity values to pixels.
- ///
- public class TriangleResampler : IResampler
- {
- ///
- public float Radius => 1;
-
- ///
- public float GetValue(float x)
- {
- if (x < 0)
- {
- x = -x;
- }
-
- if (x < 1)
- {
- return 1 - x;
- }
-
- return 0;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resamplers/WelchResampler.cs b/src/ImageProcessorCore - Copy/Samplers/Resamplers/WelchResampler.cs
deleted file mode 100644
index 3ecaa6a747..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resamplers/WelchResampler.cs
+++ /dev/null
@@ -1,33 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- ///
- /// The function implements the welch algorithm.
- ///
- ///
- public class WelchResampler : IResampler
- {
- ///
- public float Radius => 3;
-
- ///
- public float GetValue(float x)
- {
- if (x < 0)
- {
- x = -x;
- }
-
- if (x < 3)
- {
- return ImageMaths.SinC(x) * (1.0f - (x * x / 9.0f));
- }
-
- return 0;
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Resize.cs b/src/ImageProcessorCore - Copy/Samplers/Resize.cs
deleted file mode 100644
index 2eadd7a11c..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Resize.cs
+++ /dev/null
@@ -1,134 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-// -------------------------------------------------------------------------------------------------------------------
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Resizes an image in accordance with the given .
- ///
- /// The image to resize.
- /// The resize options.
- /// A delegate which is called as progress is made processing the image.
- /// 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)
- {
- // Ensure size is populated across both dimensions.
- if (options.Size.Width == 0 && options.Size.Height > 0)
- {
- options.Size = new Size(source.Width * options.Size.Height / source.Height, options.Size.Height);
- }
-
- if (options.Size.Height == 0 && options.Size.Width > 0)
- {
- options.Size = new Size(options.Size.Width, source.Height * options.Size.Width / source.Width);
- }
-
- Rectangle targetRectangle = ResizeHelper.CalculateTargetLocationAndBounds(source, options);
-
- return Resize(source, options.Size.Width, options.Size.Height, options.Sampler, source.Bounds, targetRectangle, options.Compand, progressHandler);
- }
-
- ///
- /// Resizes an image to the given width and height.
- ///
- /// The image to resize.
- /// The target image width.
- /// The target image height.
- /// A delegate which is called as progress is made processing the image.
- /// 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)
- {
- return Resize(source, width, height, new BicubicResampler(), false, progressHandler);
- }
-
- ///
- /// Resizes an image to the given width and height.
- ///
- /// The image to resize.
- /// The target image width.
- /// The target image height.
- /// Whether to compress and expand the image color-space to gamma correct the image during processing.
- /// A delegate which is called as progress is made processing the image.
- /// 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)
- {
- return Resize(source, width, height, new BicubicResampler(), compand, progressHandler);
- }
-
- ///
- /// Resizes an image to the given width and height with the given sampler.
- ///
- /// The image to resize.
- /// The target image width.
- /// The target image height.
- /// The to perform the resampling.
- /// Whether to compress and expand the image color-space to gamma correct the image during processing.
- /// A delegate which is called as progress is made processing the image.
- /// 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)
- {
- return Resize(source, width, height, sampler, source.Bounds, new Rectangle(0, 0, width, height), compand, progressHandler);
- }
-
- ///
- /// Resizes an image to the given width and height with the given sampler and
- /// source rectangle.
- ///
- /// The image to resize.
- /// The target image width.
- /// The target image height.
- /// The to perform the resampling.
- ///
- /// The structure that specifies the portion of the image object to draw.
- ///
- ///
- /// The structure that specifies the portion of the target image object to draw to.
- ///
- /// Whether to compress and expand the image color-space to gamma correct the image during processing.
- /// A delegate which is called as progress is made processing the image.
- /// 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)
- {
- if (width == 0 && height > 0)
- {
- width = source.Width * height / source.Height;
- targetRectangle.Width = width;
- }
-
- if (height == 0 && width > 0)
- {
- height = source.Height * width / source.Width;
- targetRectangle.Height = height;
- }
-
- Guard.MustBeGreaterThan(width, 0, nameof(width));
- Guard.MustBeGreaterThan(height, 0, nameof(height));
-
- ResizeProcessor processor = new ResizeProcessor(sampler) { Compand = compand };
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(width, height, sourceRectangle, targetRectangle, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Rotate.cs b/src/ImageProcessorCore - Copy/Samplers/Rotate.cs
deleted file mode 100644
index fa30d9d342..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Rotate.cs
+++ /dev/null
@@ -1,50 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Rotates an image by the given angle in degrees, expanding the image to fit the rotated result.
- ///
- /// The image to rotate.
- /// The angle in degrees to perform the rotation.
- /// A delegate which is called as progress is made processing the image.
- /// The
- public static Image Rotate(this Image source, float degrees, ProgressEventHandler progressHandler = null)
- {
- return Rotate(source, degrees, true, progressHandler);
- }
-
- ///
- /// Rotates an image by the given angle in degrees.
- ///
- /// The image to rotate.
- /// The angle in degrees to perform the rotation.
- /// Whether to expand the image to fit the rotated result.
- /// A delegate which is called as progress is made processing the image.
- /// The
- public static Image Rotate(this Image source, float degrees, bool expand, ProgressEventHandler progressHandler = null)
- {
- RotateProcessor processor = new RotateProcessor { Angle = degrees, Expand = expand };
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(source.Width, source.Height, source.Bounds, source.Bounds, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/RotateFlip.cs b/src/ImageProcessorCore - Copy/Samplers/RotateFlip.cs
deleted file mode 100644
index 93449bcd06..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/RotateFlip.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Rotates and flips an image by the given instructions.
- ///
- /// The image to rotate, flip, or both.
- /// The to perform the rotation.
- /// The to perform the flip.
- /// A delegate which is called as progress is made processing the image.
- /// The
- public static Image RotateFlip(this Image source, RotateType rotateType, FlipType flipType, ProgressEventHandler progressHandler = null)
- {
- RotateFlipProcessor processor = new RotateFlipProcessor(rotateType, flipType);
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(source.Width, source.Height, source.Bounds, source.Bounds, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/Samplers/Skew.cs b/src/ImageProcessorCore - Copy/Samplers/Skew.cs
deleted file mode 100644
index 904f1d89df..0000000000
--- a/src/ImageProcessorCore - Copy/Samplers/Skew.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using Processors;
-
- ///
- /// Extension methods for the type.
- ///
- public static partial class ImageExtensions
- {
- ///
- /// Skews an image by the given angles in degrees, expanding the image to fit the skewed result.
- ///
- /// The image to skew.
- /// The angle in degrees to perform the rotation along the x-axis.
- /// The angle in degrees to perform the rotation along the y-axis.
- /// A delegate which is called as progress is made processing the image.
- /// The
- public static Image Skew(this Image source, float degreesX, float degreesY, ProgressEventHandler progressHandler = null)
- {
- return Skew(source, degreesX, degreesY, true, progressHandler);
- }
-
- ///
- /// Skews an image by the given angles in degrees.
- ///
- /// The image to skew.
- /// The angle in degrees to perform the rotation along the x-axis.
- /// The angle in degrees to perform the rotation along the y-axis.
- /// Whether to expand the image to fit the skewed result.
- /// A delegate which is called as progress is made processing the image.
- /// The
- public static Image Skew(this Image source, float degreesX, float degreesY, bool expand, ProgressEventHandler progressHandler = null)
- {
- SkewProcessor processor = new SkewProcessor { AngleX = degreesX, AngleY = degreesY, Expand = expand };
- processor.OnProgress += progressHandler;
-
- try
- {
- return source.Process(source.Width, source.Height, source.Bounds, source.Bounds, processor);
- }
- finally
- {
- processor.OnProgress -= progressHandler;
- }
- }
- }
-}
diff --git a/src/ImageProcessorCore - Copy/project.json b/src/ImageProcessorCore - Copy/project.json
deleted file mode 100644
index e3800d495e..0000000000
--- a/src/ImageProcessorCore - Copy/project.json
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "version": "1.0.0-*",
- "title": "ImageProcessorCore",
- "description": "A cross-platform library for processing of image files written in C#",
- "authors": [
- "James Jackson-South and contributors"
- ],
- "packOptions": {
- "projectUrl": "https://github.com/JimBobSquarePants/ImageProcessor",
- "licenseUrl": "http://www.apache.org/licenses/LICENSE-2.0",
- "tags": [
- "Image Resize Crop Quality Gif Jpg Jpeg Bitmap Png Fluent Animated"
- ]
- },
- "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.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": {}
- }
-}
\ No newline at end of file