Browse Source

Now faster than System.Drawing.

Former-commit-id: 14ac44a018e4525cf65c19e3864840b4d6934981
Former-commit-id: b6d60bd3b96b352577dfd53a6cdd8f0d237d6a91
Former-commit-id: a0c275d2ed132c6d87f01c2469fd1b7d69e9dc62
af/merge-core
James Jackson-South 10 years ago
parent
commit
0cdc209c32
  1. 122
      src/ImageProcessorCore/PackedVector/Bgra32.cs
  2. 48
      src/ImageProcessorCore/PackedVector/IPackedVector.cs
  3. 34
      src/ImageProcessorCore/Samplers/Processors/ResizeProcessor.cs

122
src/ImageProcessorCore/PackedVector/Bgra32.cs

@ -10,7 +10,7 @@ namespace ImageProcessorCore
using System.Runtime.InteropServices;
/// <summary>
/// Packed vector type containing four 8-bit unsigned normalized values ranging from 0 to 1.
/// Packed vector type containing four 8-bit unsigned normalized values ranging from 0 to 255.
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public struct Bgra32 : IPackedVector<Bgra32, uint>, IEquatable<Bgra32>
@ -124,78 +124,6 @@ namespace ImageProcessorCore
return left.packedValue != right.packedValue;
}
/// <inheritdoc/>
public void Add(Bgra32 value)
{
this.B = Clamp(this.B + value.B);
this.G = Clamp(this.G + value.G);
this.R = Clamp(this.R + value.R);
this.A = Clamp(this.A + value.A);
}
/// <inheritdoc/>
public void Subtract(Bgra32 value)
{
this.B = Clamp(this.B - value.B);
this.G = Clamp(this.G - value.G);
this.R = Clamp(this.R - value.R);
this.A = Clamp(this.A - value.A);
}
/// <inheritdoc/>
public void Multiply(Bgra32 value)
{
this.B = Clamp(this.B * value.B);
this.G = Clamp(this.G * value.G);
this.R = Clamp(this.R * value.R);
this.A = Clamp(this.A * value.A);
}
/// <inheritdoc/>
public void Multiply(float value)
{
this.B = Clamp(this.B * value);
this.G = Clamp(this.G * value);
this.R = Clamp(this.R * value);
this.A = Clamp(this.A * value);
}
/// <inheritdoc/>
public void Multiply(double value)
{
this.B = Clamp(this.B * value);
this.G = Clamp(this.G * value);
this.R = Clamp(this.R * value);
this.A = Clamp(this.A * value);
}
/// <inheritdoc/>
public void Divide(Bgra32 value)
{
this.B = Clamp((float)this.B / value.B);
this.G = Clamp((float)this.G / value.G);
this.R = Clamp((float)this.R / value.R);
this.A = Clamp((float)this.A / value.A);
}
/// <inheritdoc/>
public void Divide(float value)
{
this.B = Clamp(this.B / value);
this.G = Clamp(this.G / value);
this.R = Clamp(this.R / value);
this.A = Clamp(this.A / value);
}
/// <inheritdoc/>
public void Divide(double value)
{
this.B = Clamp(this.B / value);
this.G = Clamp(this.G / value);
this.R = Clamp(this.R / value);
this.A = Clamp(this.A / value);
}
/// <inheritdoc/>
public uint PackedValue()
{
@ -260,52 +188,6 @@ namespace ImageProcessorCore
return this.GetHashCode(this);
}
/// <summary>
/// Clamps the value to the acceptable byte range.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>
/// The <see cref="float"/>.
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static byte Clamp(float value)
{
if (value > 255)
{
return 255;
}
if (value < 0)
{
return 0;
}
return (byte)value;
}
/// <summary>
/// Clamps the value to the acceptable byte range.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>
/// The <see cref="double"/>.
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static byte Clamp(double value)
{
if (value > 255)
{
return 255;
}
if (value < 0)
{
return 0;
}
return (byte)value;
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
@ -321,4 +203,4 @@ namespace ImageProcessorCore
return packed.packedValue.GetHashCode();
}
}
}
}

48
src/ImageProcessorCore/PackedVector/IPackedVector.cs

@ -24,54 +24,6 @@ namespace ImageProcessorCore
/// The <see cref="TP"/>.
/// </returns>
TP PackedValue();
/// <summary>
/// Adds the given <see cref="T"/> to the current instance.
/// </summary>
/// <param name="value">The packed vector to add.</param>
void Add(T value);
/// <summary>
/// Subtracts the given <see cref="T"/> from the current instance.
/// </summary>
/// <param name="value">The packed vector to subtract.</param>
void Subtract(T value);
/// <summary>
/// Multiplies the given current instance by given the <see cref="T"/>.
/// </summary>
/// <param name="value">The packed vector to multiply by.</param>
void Multiply(T value);
/// <summary>
/// Multiplies the given current instance by given the value.
/// </summary>
/// <param name="value">The value to multiply by.</param>
void Multiply(float value);
/// <summary>
/// Multiplies the given current instance by given the value.
/// </summary>
/// <param name="value">The value to multiply by.</param>
void Multiply(double value);
/// <summary>
/// Divides the given current instance by given the <see cref="T"/>.
/// </summary>
/// <param name="value">The packed vector to divide by.</param>
void Divide(T value);
/// <summary>
/// Divides the given current instance by given the value.
/// </summary>
/// <param name="value">The value to divide by.</param>
void Divide(float value);
/// <summary>
/// Divides the given current instance by given the value.
/// </summary>
/// <param name="value">The value to divide by.</param>
void Divide(double value);
}
/// <summary>

34
src/ImageProcessorCore/Samplers/Processors/ResizeProcessor.cs

@ -134,21 +134,14 @@ namespace ImageProcessorCore.Processors
Weight[] horizontalValues = this.HorizontalWeights[offsetX].Values;
// Destination color components
T destination = default(T);
Vector4 destination = Vector4.Zero;
for (int i = 0; i < sum; i++)
{
Weight xw = horizontalValues[i];
int originX = xw.Index;
T sourceColor = sourcePixels[originX, y];
//Color sourceColor = compand
// ? Color.Expand(sourcePixels[originX, y])
// : sourcePixels[originX, y];
//destination += sourceColor * xw.Value;
sourceColor.Multiply(xw.Value);
destination.Add(sourceColor);
Vector4 sourceColor = sourcePixels[originX, y].ToVector4();
destination += sourceColor * (float)xw.Value;
}
//if (compand)
@ -156,7 +149,9 @@ namespace ImageProcessorCore.Processors
// destination = Color.Compress(destination);
//}
firstPassPixels[x, y] = destination;
T d = default(T);
d.PackVector(destination);
firstPassPixels[x, y] = d;
}
}
});
@ -177,21 +172,14 @@ namespace ImageProcessorCore.Processors
for (int x = 0; x < width; x++)
{
// Destination color components
T destination = default(T);
Vector4 destination = Vector4.Zero;
for (int i = 0; i < sum; i++)
{
Weight yw = verticalValues[i];
int originY = yw.Index;
T sourceColor = firstPassPixels[x, originY];
//Color sourceColor = compand
// ? Color.Expand(firstPassPixels[x, originY])
// : firstPassPixels[x, originY];
//destination += sourceColor * yw.Value;
sourceColor.Multiply(yw.Value);
destination.Add(sourceColor);
Vector4 sourceColor = firstPassPixels[x, originY].ToVector4();
destination += sourceColor * (float)yw.Value;
}
//if (compand)
@ -199,7 +187,9 @@ namespace ImageProcessorCore.Processors
// destination = Color.Compress(destination);
//}
targetPixels[x, y] = destination;
T d = default(T);
d.PackVector(destination);
targetPixels[x, y] = d;
}
}

Loading…
Cancel
Save