Browse Source

dropped shared helpers

pull/69/head
Scott Williams 9 years ago
parent
commit
ae77459ab4
  1. 39
      src/ImageSharp.Formats.Gif/Helpers/ComparableExtensions.cs
  2. 30
      src/ImageSharp.Formats.Gif/Helpers/ImageMaths.cs
  3. 46
      src/ImageSharp.Formats.Gif/Helpers/StreamExtensions.cs
  4. 63
      src/ImageSharp.Formats.Jpeg/Helpers/ComparableExtensions.cs
  5. 45
      src/ImageSharp.Formats.Png/Helpers/ByteExtensions.cs
  6. 52
      src/ImageSharp.Formats.Png/Helpers/ComparableExtensions.cs
  7. 30
      src/ImageSharp.Formats.Png/Helpers/ImageMaths.cs
  8. 46
      src/ImageSharp.Formats.Png/Helpers/StreamExtensions.cs
  9. 182
      src/ImageSharp.Processing/ComparableExtensions.cs
  10. 18
      src/ImageSharp.Processing/Constants.cs
  11. 273
      src/ImageSharp.Processing/ImageMaths.cs
  12. 2
      src/ImageSharp/Common/Helpers/Guard.cs
  13. 9
      src/ImageSharp/Properties/AssemblyInfo.cs

39
src/ImageSharp.Formats.Gif/Helpers/ComparableExtensions.cs

@ -1,39 +0,0 @@
// <copyright file="ComparableExtensions.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
/// <summary>
/// Extension methods for classes that implement <see cref="IComparable{T}"/>.
/// </summary>
internal static class ComparableExtensions
{
/// <summary>
/// Restricts a <see cref="int"/> to be within a specified range.
/// </summary>
/// <param name="value">The The value to clamp.</param>
/// <param name="min">The minimum value. If value is less than min, min will be returned.</param>
/// <param name="max">The maximum value. If value is greater than max, max will be returned.</param>
/// <returns>
/// The <see cref="int"/> representing the clamped value.
/// </returns>
public static int Clamp(this int value, int min, int max)
{
if (value > max)
{
return max;
}
if (value < min)
{
return min;
}
return value;
}
}
}

30
src/ImageSharp.Formats.Gif/Helpers/ImageMaths.cs

@ -1,30 +0,0 @@
// <copyright file="ImageMaths.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
using System.Linq;
using System.Numerics;
/// <summary>
/// Provides common mathematical methods.
/// </summary>
internal static class ImageMaths
{
/// <summary>
/// Returns how many bits are required to store the specified number of colors.
/// Performs a Log2() on the value.
/// </summary>
/// <param name="colors">The number of colors.</param>
/// <returns>
/// The <see cref="int"/>
/// </returns>
public static int GetBitsNeededForColorDepth(int colors)
{
return (int)Math.Ceiling(Math.Log(colors, 2));
}
}
}

46
src/ImageSharp.Formats.Gif/Helpers/StreamExtensions.cs

@ -1,46 +0,0 @@
// <copyright file="StreamExtensions.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System.Buffers;
using System.IO;
/// <summary>
/// Extension methods for the <see cref="Stream"/> type.
/// </summary>
internal static class StreamExtensions
{
/// <summary>
/// Skips the number of bytes in the given stream.
/// </summary>
/// <param name="stream">The stream.</param>
/// <param name="count">The count.</param>
public static void Skip(this Stream stream, int count)
{
if (count < 1)
{
return;
}
if (stream.CanSeek)
{
stream.Position += count;
}
else
{
byte[] foo = ArrayPool<byte>.Shared.Rent(count);
try
{
stream.Read(foo, 0, count);
}
finally
{
ArrayPool<byte>.Shared.Return(foo);
}
}
}
}
}

63
src/ImageSharp.Formats.Jpeg/Helpers/ComparableExtensions.cs

@ -1,63 +0,0 @@
// <copyright file="ComparableExtensions.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
/// <summary>
/// Extension methods for classes that implement <see cref="IComparable{T}"/>.
/// </summary>
internal static class ComparableExtensions
{
/// <summary>
/// Restricts a <see cref="int"/> to be within a specified range.
/// </summary>
/// <param name="value">The The value to clamp.</param>
/// <param name="min">The minimum value. If value is less than min, min will be returned.</param>
/// <param name="max">The maximum value. If value is greater than max, max will be returned.</param>
/// <returns>
/// The <see cref="int"/> representing the clamped value.
/// </returns>
public static int Clamp(this int value, int min, int max)
{
if (value > max)
{
return max;
}
if (value < min)
{
return min;
}
return value;
}
/// <summary>
/// Restricts a <see cref="float"/> to be within a specified range.
/// </summary>
/// <param name="value">The The value to clamp.</param>
/// <param name="min">The minimum value. If value is less than min, min will be returned.</param>
/// <param name="max">The maximum value. If value is greater than max, max will be returned.</param>
/// <returns>
/// The <see cref="float"/> representing the clamped value.
/// </returns>
public static float Clamp(this float value, float min, float max)
{
if (value > max)
{
return max;
}
if (value < min)
{
return min;
}
return value;
}
}
}

45
src/ImageSharp.Formats.Png/Helpers/ByteExtensions.cs

@ -1,45 +0,0 @@
// <copyright file="ByteExtensions.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
/// <summary>
/// Extension methods for the <see cref="byte"/> struct.
/// </summary>
internal static class ByteExtensions
{
/// <summary>
/// Optimized <see cref="T:byte[]"/> reversal algorithm.
/// </summary>
/// <param name="source">The byte array.</param>
public static void ReverseBytes(this byte[] source)
{
ReverseBytes(source, 0, source.Length);
}
/// <summary>
/// Optimized <see cref="T:byte[]"/> reversal algorithm.
/// </summary>
/// <param name="source">The byte array.</param>
/// <param name="index">The index.</param>
/// <param name="length">The length.</param>
/// <exception cref="System.ArgumentNullException"><paramref name="source"/> is null.</exception>
public static void ReverseBytes(this byte[] source, int index, int length)
{
Guard.NotNull(source, nameof(source));
int i = index;
int j = index + length - 1;
while (i < j)
{
byte temp = source[i];
source[i] = source[j];
source[j] = temp;
i++;
j--;
}
}
}
}

52
src/ImageSharp.Formats.Png/Helpers/ComparableExtensions.cs

@ -1,52 +0,0 @@
// <copyright file="ComparableExtensions.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
/// <summary>
/// Extension methods for classes that implement <see cref="IComparable{T}"/>.
/// </summary>
internal static class ComparableExtensions
{
/// <summary>
/// Restricts a <see cref="int"/> to be within a specified range.
/// </summary>
/// <param name="value">The The value to clamp.</param>
/// <param name="min">The minimum value. If value is less than min, min will be returned.</param>
/// <param name="max">The maximum value. If value is greater than max, max will be returned.</param>
/// <returns>
/// The <see cref="int"/> representing the clamped value.
/// </returns>
public static int Clamp(this int value, int min, int max)
{
if (value > max)
{
return max;
}
if (value < min)
{
return min;
}
return value;
}
/// <summary>
/// Swaps the references to two objects in memory.
/// </summary>
/// <param name="first">The first reference.</param>
/// <param name="second">The second reference.</param>
/// <typeparam name="T">The type of object.</typeparam>
public static void Swap<T>(ref T first, ref T second)
{
T temp = second;
second = first;
first = temp;
}
}
}

30
src/ImageSharp.Formats.Png/Helpers/ImageMaths.cs

@ -1,30 +0,0 @@
// <copyright file="ImageMaths.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System;
using System.Linq;
using System.Numerics;
/// <summary>
/// Provides common mathematical methods.
/// </summary>
internal static class ImageMaths
{
/// <summary>
/// Returns how many bits are required to store the specified number of colors.
/// Performs a Log2() on the value.
/// </summary>
/// <param name="colors">The number of colors.</param>
/// <returns>
/// The <see cref="int"/>
/// </returns>
public static int GetBitsNeededForColorDepth(int colors)
{
return (int)Math.Ceiling(Math.Log(colors, 2));
}
}
}

46
src/ImageSharp.Formats.Png/Helpers/StreamExtensions.cs

@ -1,46 +0,0 @@
// <copyright file="StreamExtensions.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp
{
using System.Buffers;
using System.IO;
/// <summary>
/// Extension methods for the <see cref="Stream"/> type.
/// </summary>
internal static class StreamExtensions
{
/// <summary>
/// Skips the number of bytes in the given stream.
/// </summary>
/// <param name="stream">The stream.</param>
/// <param name="count">The count.</param>
public static void Skip(this Stream stream, int count)
{
if (count < 1)
{
return;
}
if (stream.CanSeek)
{
stream.Position += count;
}
else
{
byte[] foo = ArrayPool<byte>.Shared.Rent(count);
try
{
stream.Read(foo, 0, count);
}
finally
{
ArrayPool<byte>.Shared.Return(foo);
}
}
}
}
}

182
src/ImageSharp.Processing/ComparableExtensions.cs

@ -1,182 +0,0 @@
// <copyright file="ComparableExtensions.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Processing
{
using System;
/// <summary>
/// Extension methods for classes that implement <see cref="IComparable{T}"/>.
/// </summary>
internal static class ComparableExtensions
{
/// <summary>
/// Restricts a <see cref="byte"/> to be within a specified range.
/// </summary>
/// <param name="value">The The value to clamp.</param>
/// <param name="min">The minimum value. If value is less than min, min will be returned.</param>
/// <param name="max">The maximum value. If value is greater than max, max will be returned.</param>
/// <returns>
/// The <see cref="byte"/> representing the clamped value.
/// </returns>
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;
}
/// <summary>
/// Restricts a <see cref="uint"/> to be within a specified range.
/// </summary>
/// <param name="value">The The value to clamp.</param>
/// <param name="min">The minimum value. If value is less than min, min will be returned.</param>
/// <param name="max">The maximum value. If value is greater than max, max will be returned.</param>
/// <returns>
/// The <see cref="int"/> representing the clamped value.
/// </returns>
public static uint Clamp(this uint value, uint min, uint max)
{
if (value > max)
{
return max;
}
if (value < min)
{
return min;
}
return value;
}
/// <summary>
/// Restricts a <see cref="int"/> to be within a specified range.
/// </summary>
/// <param name="value">The The value to clamp.</param>
/// <param name="min">The minimum value. If value is less than min, min will be returned.</param>
/// <param name="max">The maximum value. If value is greater than max, max will be returned.</param>
/// <returns>
/// The <see cref="int"/> representing the clamped value.
/// </returns>
public static int Clamp(this int value, int min, int max)
{
if (value > max)
{
return max;
}
if (value < min)
{
return min;
}
return value;
}
/// <summary>
/// Restricts a <see cref="float"/> to be within a specified range.
/// </summary>
/// <param name="value">The The value to clamp.</param>
/// <param name="min">The minimum value. If value is less than min, min will be returned.</param>
/// <param name="max">The maximum value. If value is greater than max, max will be returned.</param>
/// <returns>
/// The <see cref="float"/> representing the clamped value.
/// </returns>
public static float Clamp(this float value, float min, float max)
{
if (value > max)
{
return max;
}
if (value < min)
{
return min;
}
return value;
}
/// <summary>
/// Restricts a <see cref="double"/> to be within a specified range.
/// </summary>
/// <param name="value">The The value to clamp.</param>
/// <param name="min">The minimum value. If value is less than min, min will be returned.</param>
/// <param name="max">The maximum value. If value is greater than max, max will be returned.</param>
/// <returns>
/// The <see cref="double"/> representing the clamped value.
/// </returns>
public static double Clamp(this double value, double min, double max)
{
if (value > max)
{
return max;
}
if (value < min)
{
return min;
}
return value;
}
/// <summary>
/// Converts an <see cref="int"/> to a <see cref="byte"/> first restricting the value between the
/// minimum and maximum allowable ranges.
/// </summary>
/// <param name="value">The <see cref="int"/> this method extends.</param>
/// <returns>The <see cref="byte"/></returns>
public static byte ToByte(this int value)
{
return (byte)value.Clamp(0, 255);
}
/// <summary>
/// Converts an <see cref="float"/> to a <see cref="byte"/> first restricting the value between the
/// minimum and maximum allowable ranges.
/// </summary>
/// <param name="value">The <see cref="float"/> this method extends.</param>
/// <returns>The <see cref="byte"/></returns>
public static byte ToByte(this float value)
{
return (byte)value.Clamp(0, 255);
}
/// <summary>
/// Converts an <see cref="double"/> to a <see cref="byte"/> first restricting the value between the
/// minimum and maximum allowable ranges.
/// </summary>
/// <param name="value">The <see cref="double"/> this method extends.</param>
/// <returns>The <see cref="byte"/></returns>
public static byte ToByte(this double value)
{
return (byte)value.Clamp(0, 255);
}
/// <summary>
/// Swaps the references to two objects in memory.
/// </summary>
/// <param name="first">The first reference.</param>
/// <param name="second">The second reference.</param>
/// <typeparam name="T">The type of object.</typeparam>
public static void Swap<T>(ref T first, ref T second)
{
T temp = second;
second = first;
first = temp;
}
}
}

18
src/ImageSharp.Processing/Constants.cs

@ -1,18 +0,0 @@
// <copyright file="Constants.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Processing
{
/// <summary>
/// Common constants used throughout the project
/// </summary>
internal static class Constants
{
/// <summary>
/// The epsilon for comparing floating point numbers.
/// </summary>
public static readonly float Epsilon = 0.001f;
}
}

273
src/ImageSharp.Processing/ImageMaths.cs

@ -1,273 +0,0 @@
// <copyright file="ImageMaths.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Processing
{
using System;
using System.Linq;
using System.Numerics;
/// <summary>
/// Provides common mathematical methods.
/// </summary>
internal static class ImageMaths
{
/// <summary>
/// Implementation of 1D Gaussian G(x) function
/// </summary>
/// <param name="x">The x provided to G(x).</param>
/// <param name="sigma">The spread of the blur.</param>
/// <returns>The Gaussian G(x)</returns>
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;
}
/// <summary>
/// Returns the result of a B-C filter against the given value.
/// <see href="http://www.imagemagick.org/Usage/filter/#cubic_bc"/>
/// </summary>
/// <param name="x">The value to process.</param>
/// <param name="b">The B-Spline curve variable.</param>
/// <param name="c">The Cardinal curve variable.</param>
/// <returns>
/// The <see cref="float"/>.
/// </returns>
public static float GetBcValue(float x, float b, float c)
{
float temp;
if (x < 0F)
{
x = -x;
}
temp = x * x;
if (x < 1F)
{
x = ((12 - (9 * b) - (6 * c)) * (x * temp)) + ((-18 + (12 * b) + (6 * c)) * temp) + (6 - (2 * b));
return x / 6F;
}
if (x < 2F)
{
x = ((-b - (6 * c)) * (x * temp)) + (((6 * b) + (30 * c)) * temp) + (((-12 * b) - (48 * c)) * x) + ((8 * b) + (24 * c));
return x / 6F;
}
return 0F;
}
/// <summary>
/// Gets the result of a sine cardinal function for the given value.
/// </summary>
/// <param name="x">The value to calculate the result for.</param>
/// <returns>
/// The <see cref="float"/>.
/// </returns>
public static float SinC(float x)
{
if (Math.Abs(x) > Constants.Epsilon)
{
x *= (float)Math.PI;
return Clean((float)Math.Sin(x) / x);
}
return 1.0f;
}
/// <summary>
/// Returns the given degrees converted to radians.
/// </summary>
/// <param name="degrees">The angle in degrees.</param>
/// <returns>
/// The <see cref="float"/> representing the degree as radians.
/// </returns>
public static float DegreesToRadians(float degrees)
{
return degrees * (float)(Math.PI / 180);
}
/// <summary>
/// Gets the bounding <see cref="Rectangle"/> from the given points.
/// </summary>
/// <param name="topLeft">
/// The <see cref="Point"/> designating the top left position.
/// </param>
/// <param name="bottomRight">
/// The <see cref="Point"/> designating the bottom right position.
/// </param>
/// <returns>
/// The bounding <see cref="Rectangle"/>.
/// </returns>
public static Rectangle GetBoundingRectangle(Point topLeft, Point bottomRight)
{
return new Rectangle(topLeft.X, topLeft.Y, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y);
}
/// <summary>
/// Gets the bounding <see cref="Rectangle"/> from the given matrix.
/// </summary>
/// <param name="rectangle">The source rectangle.</param>
/// <param name="matrix">The transformation matrix.</param>
/// <returns>
/// The <see cref="Rectangle"/>.
/// </returns>
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);
}
/// <summary>
/// Finds the bounding rectangle based on the first instance of any color component other
/// than the given one.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <param name="bitmap">The <see cref="Image"/> to search within.</param>
/// <param name="componentValue">The color component value to remove.</param>
/// <param name="channel">The <see cref="RgbaComponent"/> channel to test against.</param>
/// <returns>
/// The <see cref="Rectangle"/>.
/// </returns>
public static Rectangle GetFilteredBoundingRectangle<TColor>(ImageBase<TColor> bitmap, float componentValue, RgbaComponent channel = RgbaComponent.B)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
int width = bitmap.Width;
int height = bitmap.Height;
Point topLeft = default(Point);
Point bottomRight = default(Point);
Func<PixelAccessor<TColor>, int, int, float, bool> delegateFunc;
// Determine which channel to check against
switch (channel)
{
case RgbaComponent.R:
delegateFunc = (pixels, x, y, b) => Math.Abs(pixels[x, y].ToVector4().X - b) > Constants.Epsilon;
break;
case RgbaComponent.G:
delegateFunc = (pixels, x, y, b) => Math.Abs(pixels[x, y].ToVector4().Y - b) > Constants.Epsilon;
break;
case RgbaComponent.B:
delegateFunc = (pixels, x, y, b) => Math.Abs(pixels[x, y].ToVector4().Z - b) > Constants.Epsilon;
break;
default:
delegateFunc = (pixels, x, y, b) => Math.Abs(pixels[x, y].ToVector4().W - b) > Constants.Epsilon;
break;
}
Func<PixelAccessor<TColor>, int> 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<PixelAccessor<TColor>, int> 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<PixelAccessor<TColor>, int> 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<PixelAccessor<TColor>, int> 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<TColor> 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);
}
/// <summary>
/// Ensures that any passed double is correctly rounded to zero
/// </summary>
/// <param name="x">The value to clean.</param>
/// <returns>
/// The <see cref="float"/>
/// </returns>.
private static float Clean(float x)
{
if (Math.Abs(x) < Constants.Epsilon)
{
return 0F;
}
return x;
}
}
}

2
src/ImageSharp/Common/Helpers/Guard.cs

@ -14,7 +14,7 @@ namespace ImageSharp
/// Provides methods to protect against invalid parameters.
/// </summary>
[DebuggerStepThrough]
public static class Guard
internal static class Guard
{
/// <summary>
/// Verifies, that the method parameter with specified object value is not null

9
src/ImageSharp/Properties/AssemblyInfo.cs

@ -37,4 +37,11 @@ using System.Runtime.CompilerServices;
// Ensure the internals can be tested.
[assembly: InternalsVisibleTo("ImageSharp.Benchmarks")]
[assembly: InternalsVisibleTo("ImageSharp.Tests")]
[assembly: InternalsVisibleTo("ImageSharp.Tests46")]
// Ensure the other projects can see the internal helpers
[assembly: InternalsVisibleTo("ImageSharp.Drawing")]
[assembly: InternalsVisibleTo("ImageSharp.Formats.Bmp")]
[assembly: InternalsVisibleTo("ImageSharp.Formats.Gif")]
[assembly: InternalsVisibleTo("ImageSharp.Formats.Jpeg")]
[assembly: InternalsVisibleTo("ImageSharp.Formats.Png")]
[assembly: InternalsVisibleTo("ImageSharp.Processing")]
Loading…
Cancel
Save