Browse Source

No more Vector4Utils & ImageMath

js/color-alpha-handling
James Jackson-South 5 years ago
parent
commit
8d3cddab30
  1. 14
      src/ImageSharp/Color/Color.cs
  2. 177
      src/ImageSharp/Common/Helpers/ColorNumerics.cs
  3. 12
      src/ImageSharp/Common/Helpers/DenseMatrixUtils.cs
  4. 257
      src/ImageSharp/Common/Helpers/ImageMath.cs
  5. 123
      src/ImageSharp/Common/Helpers/Numerics.cs
  6. 169
      src/ImageSharp/Common/Helpers/Vector4Utils.cs
  7. 4
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  8. 6
      src/ImageSharp/Formats/Gif/GifEncoderCore.cs
  9. 6
      src/ImageSharp/Formats/Png/PngEncoderCore.cs
  10. 4
      src/ImageSharp/Formats/Png/PngEncoderOptionsHelpers.cs
  11. 4
      src/ImageSharp/Formats/Png/PngScanlineProcessor.cs
  12. 2
      src/ImageSharp/Formats/Tga/TgaEncoderCore.cs
  13. 2
      src/ImageSharp/PixelFormats/PixelImplementations/A8.cs
  14. 20
      src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs
  15. 16
      src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs
  16. 20
      src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs
  17. 52
      src/ImageSharp/PixelFormats/PixelImplementations/L16.cs
  18. 32
      src/ImageSharp/PixelFormats/PixelImplementations/L8.cs
  19. 36
      src/ImageSharp/PixelFormats/PixelImplementations/La16.cs
  20. 62
      src/ImageSharp/PixelFormats/PixelImplementations/La32.cs
  21. 16
      src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs
  22. 40
      src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs
  23. 20
      src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs
  24. 122
      src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs
  25. 4
      src/ImageSharp/PixelFormats/Utils/Vector4Converters.cs
  26. 2
      src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs
  27. 4
      src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs
  28. 2
      src/ImageSharp/Processing/Processors/Filters/FilterProcessor{TPixel}.cs
  29. 4
      src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs
  30. 4
      src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor{TPixel}.cs
  31. 2
      src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor{TPixel}.cs
  32. 2
      src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs
  33. 135
      src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor{TPixel}.cs
  34. 4
      src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtils.cs
  35. 2
      tests/ImageSharp.Benchmarks/Color/Bulk/PremultiplyVector4.cs
  36. 2
      tests/ImageSharp.Benchmarks/Color/Bulk/UnPremultiplyVector4.cs
  37. 2
      tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs
  38. 6
      tests/ImageSharp.Tests/Helpers/ColorNumericsTests.cs
  39. 46
      tests/ImageSharp.Tests/Helpers/NumericsTests.cs
  40. 56
      tests/ImageSharp.Tests/Helpers/Vector4UtilsTests.cs
  41. 6
      tests/ImageSharp.Tests/PixelFormats/L16Tests.cs
  42. 2
      tests/ImageSharp.Tests/PixelFormats/L8Tests.cs
  43. 2
      tests/ImageSharp.Tests/PixelFormats/La16Tests.cs
  44. 6
      tests/ImageSharp.Tests/PixelFormats/La32Tests.cs
  45. 24
      tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs

14
src/ImageSharp/Color/Color.cs

@ -27,19 +27,19 @@ namespace SixLabors.ImageSharp
private Color(byte r, byte g, byte b, byte a)
{
this.data = new Rgba64(
ImageMath.UpscaleFrom8BitTo16Bit(r),
ImageMath.UpscaleFrom8BitTo16Bit(g),
ImageMath.UpscaleFrom8BitTo16Bit(b),
ImageMath.UpscaleFrom8BitTo16Bit(a));
ColorNumerics.UpscaleFrom8BitTo16Bit(r),
ColorNumerics.UpscaleFrom8BitTo16Bit(g),
ColorNumerics.UpscaleFrom8BitTo16Bit(b),
ColorNumerics.UpscaleFrom8BitTo16Bit(a));
}
[MethodImpl(InliningOptions.ShortMethod)]
private Color(byte r, byte g, byte b)
{
this.data = new Rgba64(
ImageMath.UpscaleFrom8BitTo16Bit(r),
ImageMath.UpscaleFrom8BitTo16Bit(g),
ImageMath.UpscaleFrom8BitTo16Bit(b),
ColorNumerics.UpscaleFrom8BitTo16Bit(r),
ColorNumerics.UpscaleFrom8BitTo16Bit(g),
ColorNumerics.UpscaleFrom8BitTo16Bit(b),
ushort.MaxValue);
}

177
src/ImageSharp/Common/Helpers/ColorNumerics.cs

@ -0,0 +1,177 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace SixLabors.ImageSharp
{
/// <summary>
/// Provides optimized static methods for common mathematical functions specific
/// to color processing.
/// </summary>
internal static class ColorNumerics
{
/// <summary>
/// Vector for converting pixel to gray value as specified by
/// ITU-R Recommendation BT.709.
/// </summary>
private static readonly Vector4 Bt709 = new Vector4(.2126f, .7152f, .0722f, 0.0f);
/// <summary>
/// Convert a pixel value to grayscale using ITU-R Recommendation BT.709.
/// </summary>
/// <param name="vector">The vector to get the luminance from.</param>
/// <param name="luminanceLevels">
/// The number of luminance levels (256 for 8 bit, 65536 for 16 bit grayscale images).
/// </param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetBT709Luminance(ref Vector4 vector, int luminanceLevels)
=> (int)MathF.Round(Vector4.Dot(vector, Bt709) * (luminanceLevels - 1));
/// <summary>
/// Gets the luminance from the rgb components using the formula
/// as specified by ITU-R Recommendation BT.709.
/// </summary>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <returns>The <see cref="byte"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte Get8BitBT709Luminance(byte r, byte g, byte b)
=> (byte)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
/// <summary>
/// Gets the luminance from the rgb components using the formula as
/// specified by ITU-R Recommendation BT.709.
/// </summary>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <returns>The <see cref="ushort"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ushort Get16BitBT709Luminance(ushort r, ushort g, ushort b)
=> (ushort)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
/// <summary>
/// Gets the luminance from the rgb components using the formula as specified
/// by ITU-R Recommendation BT.709.
/// </summary>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <returns>The <see cref="ushort"/>.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ushort Get16BitBT709Luminance(float r, float g, float b)
=> (ushort)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
/// <summary>
/// Scales a value from a 16 bit <see cref="ushort"/> to an
/// 8 bit <see cref="byte"/> equivalent.
/// </summary>
/// <param name="component">The 8 bit component value.</param>
/// <returns>The <see cref="byte"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte DownScaleFrom16BitTo8Bit(ushort component)
{
// To scale to 8 bits From a 16-bit value V the required value (from the PNG specification) is:
//
// (V * 255) / 65535
//
// This reduces to round(V / 257), or floor((V + 128.5)/257)
//
// Represent V as the two byte value vhi.vlo. Make a guess that the
// result is the top byte of V, vhi, then the correction to this value
// is:
//
// error = floor(((V-vhi.vhi) + 128.5) / 257)
// = floor(((vlo-vhi) + 128.5) / 257)
//
// This can be approximated using integer arithmetic (and a signed
// shift):
//
// error = (vlo-vhi+128) >> 8;
//
// The approximate differs from the exact answer only when (vlo-vhi) is
// 128; it then gives a correction of +1 when the exact correction is
// 0. This gives 128 errors. The exact answer (correct for all 16-bit
// input values) is:
//
// error = (vlo-vhi+128)*65535 >> 24;
//
// An alternative arithmetic calculation which also gives no errors is:
//
// (V * 255 + 32895) >> 16
return (byte)(((component * 255) + 32895) >> 16);
}
/// <summary>
/// Scales a value from an 8 bit <see cref="byte"/> to
/// an 16 bit <see cref="ushort"/> equivalent.
/// </summary>
/// <param name="component">The 8 bit component value.</param>
/// <returns>The <see cref="ushort"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ushort UpscaleFrom8BitTo16Bit(byte component)
=> (ushort)(component * 257);
/// <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>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetBitsNeededForColorDepth(int colors)
=> Math.Max(1, (int)Math.Ceiling(Math.Log(colors, 2)));
/// <summary>
/// Returns how many colors will be created by the specified number of bits.
/// </summary>
/// <param name="bitDepth">The bit depth.</param>
/// <returns>The <see cref="int"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetColorCountForBitDepth(int bitDepth)
=> 1 << bitDepth;
/// <summary>
/// Transforms a vector by the given color matrix.
/// </summary>
/// <param name="vector">The source vector.</param>
/// <param name="matrix">The transformation color matrix.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Transform(ref Vector4 vector, ref ColorMatrix matrix)
{
float x = vector.X;
float y = vector.Y;
float z = vector.Z;
float w = vector.W;
vector.X = (x * matrix.M11) + (y * matrix.M21) + (z * matrix.M31) + (w * matrix.M41) + matrix.M51;
vector.Y = (x * matrix.M12) + (y * matrix.M22) + (z * matrix.M32) + (w * matrix.M42) + matrix.M52;
vector.Z = (x * matrix.M13) + (y * matrix.M23) + (z * matrix.M33) + (w * matrix.M43) + matrix.M53;
vector.W = (x * matrix.M14) + (y * matrix.M24) + (z * matrix.M34) + (w * matrix.M44) + matrix.M54;
}
/// <summary>
/// Bulk variant of <see cref="Transform(ref Vector4, ref ColorMatrix)"/>.
/// </summary>
/// <param name="vectors">The span of vectors</param>
/// <param name="matrix">The transformation color matrix.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Transform(Span<Vector4> vectors, ref ColorMatrix matrix)
{
ref Vector4 baseRef = ref MemoryMarshal.GetReference(vectors);
for (int i = 0; i < vectors.Length; i++)
{
ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
Transform(ref v, ref matrix);
}
}
}
}

12
src/ImageSharp/Common/Helpers/DenseMatrixUtils.cs

@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp
ref Vector4 target = ref Unsafe.Add(ref targetRowRef, column);
vector.W = target.W;
Vector4Utils.UnPremultiply(ref vector);
Numerics.UnPremultiply(ref vector);
target = vector;
}
@ -105,7 +105,7 @@ namespace SixLabors.ImageSharp
out Vector4 vector);
ref Vector4 target = ref Unsafe.Add(ref targetRowRef, column);
Vector4Utils.UnPremultiply(ref vector);
Numerics.UnPremultiply(ref vector);
target = vector;
}
@ -140,7 +140,7 @@ namespace SixLabors.ImageSharp
{
int offsetX = Numerics.Clamp(sourceOffsetColumnBase + x - radiusX, minColumn, maxColumn);
var currentColor = sourceRowSpan[offsetX].ToVector4();
Vector4Utils.Premultiply(ref currentColor);
Numerics.Premultiply(ref currentColor);
vectorX += matrixX[y, x] * currentColor;
vectorY += matrixY[y, x] * currentColor;
@ -193,7 +193,7 @@ namespace SixLabors.ImageSharp
ref Vector4 target = ref Unsafe.Add(ref targetRowRef, column);
vector.W = target.W;
Vector4Utils.UnPremultiply(ref vector);
Numerics.UnPremultiply(ref vector);
target = vector;
}
@ -238,7 +238,7 @@ namespace SixLabors.ImageSharp
ref vector);
ref Vector4 target = ref Unsafe.Add(ref targetRowRef, column);
Vector4Utils.UnPremultiply(ref vector);
Numerics.UnPremultiply(ref vector);
target = vector;
}
@ -270,7 +270,7 @@ namespace SixLabors.ImageSharp
{
int offsetX = Numerics.Clamp(sourceOffsetColumnBase + x - radiusX, minColumn, maxColumn);
var currentColor = sourceRowSpan[offsetX].ToVector4();
Vector4Utils.Premultiply(ref currentColor);
Numerics.Premultiply(ref currentColor);
vector += matrix[y, x] * currentColor;
}
}

257
src/ImageSharp/Common/Helpers/ImageMath.cs

@ -1,257 +0,0 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp
{
/// <summary>
/// Provides common mathematical methods used for image processing.
/// </summary>
internal static class ImageMath
{
/// <summary>
/// Vector for converting pixel to gray value as specified by ITU-R Recommendation BT.709.
/// </summary>
private static readonly Vector4 Bt709 = new Vector4(.2126f, .7152f, .0722f, 0.0f);
/// <summary>
/// Convert a pixel value to grayscale using ITU-R Recommendation BT.709.
/// </summary>
/// <param name="vector">The vector to get the luminance from.</param>
/// <param name="luminanceLevels">The number of luminance levels (256 for 8 bit, 65536 for 16 bit grayscale images)</param>
[MethodImpl(InliningOptions.ShortMethod)]
public static int GetBT709Luminance(ref Vector4 vector, int luminanceLevels)
=> (int)MathF.Round(Vector4.Dot(vector, Bt709) * (luminanceLevels - 1));
/// <summary>
/// Gets the luminance from the rgb components using the formula as specified by ITU-R Recommendation BT.709.
/// </summary>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <returns>The <see cref="byte"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public static byte Get8BitBT709Luminance(byte r, byte g, byte b) =>
(byte)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
/// <summary>
/// Gets the luminance from the rgb components using the formula as specified by ITU-R Recommendation BT.709.
/// </summary>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <returns>The <see cref="ushort"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public static ushort Get16BitBT709Luminance(ushort r, ushort g, ushort b) =>
(ushort)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
/// <summary>
/// Gets the luminance from the rgb components using the formula as specified by ITU-R Recommendation BT.709.
/// </summary>
/// <param name="r">The red component.</param>
/// <param name="g">The green component.</param>
/// <param name="b">The blue component.</param>
/// <returns>The <see cref="ushort"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
public static ushort Get16BitBT709Luminance(float r, float g, float b) =>
(ushort)((r * .2126F) + (g * .7152F) + (b * .0722F) + 0.5F);
/// <summary>
/// Scales a value from a 16 bit <see cref="ushort"/> to it's 8 bit <see cref="byte"/> equivalent.
/// </summary>
/// <param name="component">The 8 bit component value.</param>
/// <returns>The <see cref="byte"/></returns>
[MethodImpl(InliningOptions.ShortMethod)]
public static byte DownScaleFrom16BitTo8Bit(ushort component)
{
// To scale to 8 bits From a 16-bit value V the required value (from the PNG specification) is:
//
// (V * 255) / 65535
//
// This reduces to round(V / 257), or floor((V + 128.5)/257)
//
// Represent V as the two byte value vhi.vlo. Make a guess that the
// result is the top byte of V, vhi, then the correction to this value
// is:
//
// error = floor(((V-vhi.vhi) + 128.5) / 257)
// = floor(((vlo-vhi) + 128.5) / 257)
//
// This can be approximated using integer arithmetic (and a signed
// shift):
//
// error = (vlo-vhi+128) >> 8;
//
// The approximate differs from the exact answer only when (vlo-vhi) is
// 128; it then gives a correction of +1 when the exact correction is
// 0. This gives 128 errors. The exact answer (correct for all 16-bit
// input values) is:
//
// error = (vlo-vhi+128)*65535 >> 24;
//
// An alternative arithmetic calculation which also gives no errors is:
//
// (V * 255 + 32895) >> 16
return (byte)(((component * 255) + 32895) >> 16);
}
/// <summary>
/// Scales a value from an 8 bit <see cref="byte"/> to it's 16 bit <see cref="ushort"/> equivalent.
/// </summary>
/// <param name="component">The 8 bit component value.</param>
/// <returns>The <see cref="ushort"/></returns>
[MethodImpl(InliningOptions.ShortMethod)]
public static ushort UpscaleFrom8BitTo16Bit(byte component) => (ushort)(component * 257);
/// <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>
[MethodImpl(InliningOptions.ShortMethod)]
public static int GetBitsNeededForColorDepth(int colors) => Math.Max(1, (int)Math.Ceiling(Math.Log(colors, 2)));
/// <summary>
/// Returns how many colors will be created by the specified number of bits.
/// </summary>
/// <param name="bitDepth">The bit depth.</param>
/// <returns>The <see cref="int"/></returns>
[MethodImpl(InliningOptions.ShortMethod)]
public static int GetColorCountForBitDepth(int bitDepth) => 1 << bitDepth;
/// <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>
[MethodImpl(InliningOptions.ShortMethod)]
public static Rectangle GetBoundingRectangle(Point topLeft, Point bottomRight) => new Rectangle(topLeft.X, topLeft.Y, bottomRight.X - topLeft.X, bottomRight.Y - topLeft.Y);
/// <summary>
/// Finds the bounding rectangle based on the first instance of any color component other
/// than the given one.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="bitmap">The <see cref="Image{TPixel}"/> 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<TPixel>(ImageFrame<TPixel> bitmap, float componentValue, RgbaComponent channel = RgbaComponent.B)
where TPixel : unmanaged, IPixel<TPixel>
{
int width = bitmap.Width;
int height = bitmap.Height;
Point topLeft = default;
Point bottomRight = default;
Func<ImageFrame<TPixel>, int, int, float, bool> delegateFunc;
// Determine which channel to check against
switch (channel)
{
case RgbaComponent.R:
delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().X - b) > Constants.Epsilon;
break;
case RgbaComponent.G:
delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().Y - b) > Constants.Epsilon;
break;
case RgbaComponent.B:
delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().Z - b) > Constants.Epsilon;
break;
default:
delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().W - b) > Constants.Epsilon;
break;
}
int GetMinY(ImageFrame<TPixel> 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;
}
int GetMaxY(ImageFrame<TPixel> 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;
}
int GetMinX(ImageFrame<TPixel> 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;
}
int GetMaxX(ImageFrame<TPixel> 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 width;
}
topLeft.Y = GetMinY(bitmap);
topLeft.X = GetMinX(bitmap);
bottomRight.Y = Numerics.Clamp(GetMaxY(bitmap) + 1, 0, height);
bottomRight.X = Numerics.Clamp(GetMaxX(bitmap) + 1, 0, width);
return GetBoundingRectangle(topLeft, bottomRight);
}
}
}

123
src/ImageSharp/Common/Helpers/Numerics.cs

@ -5,6 +5,10 @@ using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
#if SUPPORTS_RUNTIME_INTRINSICS
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
#endif
namespace SixLabors.ImageSharp
{
@ -14,9 +18,15 @@ namespace SixLabors.ImageSharp
/// </summary>
internal static class Numerics
{
#if SUPPORTS_RUNTIME_INTRINSICS
private const int BlendAlphaControl = 0b_10_00_10_00;
private const int ShuffleAlphaControl = 0b_11_11_11_11;
#endif
/// <summary>
/// Determine the Greatest CommonDivisor (GCD) of two numbers.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GreatestCommonDivisor(int a, int b)
{
while (b != 0)
@ -32,6 +42,7 @@ namespace SixLabors.ImageSharp
/// <summary>
/// Determine the Least Common Multiple (LCM) of two numbers.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int LeastCommonMultiple(int a, int b)
{
// https://en.wikipedia.org/wiki/Least_common_multiple#Reduction_by_the_greatest_common_divisor
@ -262,7 +273,7 @@ namespace SixLabors.ImageSharp
/// <param name="min">The minimum inclusive value.</param>
/// <param name="max">The maximum inclusive value.</param>
/// <returns>The clamped <see cref="Vector4"/>.</returns>
[MethodImpl(InliningOptions.ShortMethod)]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4 Clamp(Vector4 value, Vector4 min, Vector4 max)
=> Vector4.Min(Vector4.Max(value, min), max);
@ -426,5 +437,115 @@ namespace SixLabors.ImageSharp
}
}
}
/// <summary>
/// Pre-multiplies the "x", "y", "z" components of a vector by its "w" component leaving the "w" component intact.
/// </summary>
/// <param name="source">The <see cref="Vector4"/> to premultiply</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Premultiply(ref Vector4 source)
{
float w = source.W;
source *= w;
source.W = w;
}
/// <summary>
/// Reverses the result of premultiplying a vector via <see cref="Premultiply(ref Vector4)"/>.
/// </summary>
/// <param name="source">The <see cref="Vector4"/> to premultiply</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void UnPremultiply(ref Vector4 source)
{
float w = source.W;
source /= w;
source.W = w;
}
/// <summary>
/// Bulk variant of <see cref="Premultiply(ref Vector4)"/>
/// </summary>
/// <param name="vectors">The span of vectors</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Premultiply(Span<Vector4> vectors)
{
#if SUPPORTS_RUNTIME_INTRINSICS
if (Avx2.IsSupported && vectors.Length >= 2)
{
ref Vector256<float> vectorsBase =
ref Unsafe.As<Vector4, Vector256<float>>(ref MemoryMarshal.GetReference(vectors));
// Divide by 2 as 4 elements per Vector4 and 8 per Vector256<float>
ref Vector256<float> vectorsLast = ref Unsafe.Add(ref vectorsBase, (IntPtr)((uint)vectors.Length / 2u));
while (Unsafe.IsAddressLessThan(ref vectorsBase, ref vectorsLast))
{
Vector256<float> source = vectorsBase;
Vector256<float> multiply = Avx.Shuffle(source, source, ShuffleAlphaControl);
vectorsBase = Avx.Blend(Avx.Multiply(source, multiply), source, BlendAlphaControl);
vectorsBase = ref Unsafe.Add(ref vectorsBase, 1);
}
if (Modulo2(vectors.Length) != 0)
{
// Vector4 fits neatly in pairs. Any overlap has to be equal to 1.
Premultiply(ref MemoryMarshal.GetReference(vectors.Slice(vectors.Length - 1)));
}
}
else
#endif
{
ref Vector4 baseRef = ref MemoryMarshal.GetReference(vectors);
for (int i = 0; i < vectors.Length; i++)
{
ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
Premultiply(ref v);
}
}
}
/// <summary>
/// Bulk variant of <see cref="UnPremultiply(ref Vector4)"/>
/// </summary>
/// <param name="vectors">The span of vectors</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void UnPremultiply(Span<Vector4> vectors)
{
#if SUPPORTS_RUNTIME_INTRINSICS
if (Avx2.IsSupported && vectors.Length >= 2)
{
ref Vector256<float> vectorsBase =
ref Unsafe.As<Vector4, Vector256<float>>(ref MemoryMarshal.GetReference(vectors));
// Divide by 2 as 4 elements per Vector4 and 8 per Vector256<float>
ref Vector256<float> vectorsLast = ref Unsafe.Add(ref vectorsBase, (IntPtr)((uint)vectors.Length / 2u));
while (Unsafe.IsAddressLessThan(ref vectorsBase, ref vectorsLast))
{
Vector256<float> source = vectorsBase;
Vector256<float> multiply = Avx.Shuffle(source, source, ShuffleAlphaControl);
vectorsBase = Avx.Blend(Avx.Divide(source, multiply), source, BlendAlphaControl);
vectorsBase = ref Unsafe.Add(ref vectorsBase, 1);
}
if (Modulo2(vectors.Length) != 0)
{
// Vector4 fits neatly in pairs. Any overlap has to be equal to 1.
UnPremultiply(ref MemoryMarshal.GetReference(vectors.Slice(vectors.Length - 1)));
}
}
else
#endif
{
ref Vector4 baseRef = ref MemoryMarshal.GetReference(vectors);
for (int i = 0; i < vectors.Length; i++)
{
ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
UnPremultiply(ref v);
}
}
}
}
}

169
src/ImageSharp/Common/Helpers/Vector4Utils.cs

@ -1,169 +0,0 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
#if SUPPORTS_RUNTIME_INTRINSICS
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
#endif
namespace SixLabors.ImageSharp
{
/// <summary>
/// Utility methods for the <see cref="Vector4"/> struct.
/// </summary>
internal static class Vector4Utils
{
private const int BlendAlphaControl = 0b_10_00_10_00;
private const int ShuffleAlphaControl = 0b_11_11_11_11;
/// <summary>
/// Pre-multiplies the "x", "y", "z" components of a vector by its "w" component leaving the "w" component intact.
/// </summary>
/// <param name="source">The <see cref="Vector4"/> to premultiply</param>
[MethodImpl(InliningOptions.ShortMethod)]
public static void Premultiply(ref Vector4 source)
{
float w = source.W;
source *= w;
source.W = w;
}
/// <summary>
/// Reverses the result of premultiplying a vector via <see cref="Premultiply(ref Vector4)"/>.
/// </summary>
/// <param name="source">The <see cref="Vector4"/> to premultiply</param>
[MethodImpl(InliningOptions.ShortMethod)]
public static void UnPremultiply(ref Vector4 source)
{
float w = source.W;
source /= w;
source.W = w;
}
/// <summary>
/// Bulk variant of <see cref="Premultiply(ref Vector4)"/>
/// </summary>
/// <param name="vectors">The span of vectors</param>
[MethodImpl(InliningOptions.ShortMethod)]
public static void Premultiply(Span<Vector4> vectors)
{
#if SUPPORTS_RUNTIME_INTRINSICS
if (Avx2.IsSupported && vectors.Length >= 2)
{
ref Vector256<float> vectorsBase =
ref Unsafe.As<Vector4, Vector256<float>>(ref MemoryMarshal.GetReference(vectors));
// Divide by 2 as 4 elements per Vector4 and 8 per Vector256<float>
ref Vector256<float> vectorsLast = ref Unsafe.Add(ref vectorsBase, (IntPtr)((uint)vectors.Length / 2u));
while (Unsafe.IsAddressLessThan(ref vectorsBase, ref vectorsLast))
{
Vector256<float> source = vectorsBase;
Vector256<float> multiply = Avx.Shuffle(source, source, ShuffleAlphaControl);
vectorsBase = Avx.Blend(Avx.Multiply(source, multiply), source, BlendAlphaControl);
vectorsBase = ref Unsafe.Add(ref vectorsBase, 1);
}
if (Numerics.Modulo2(vectors.Length) != 0)
{
// Vector4 fits neatly in pairs. Any overlap has to be equal to 1.
Premultiply(ref MemoryMarshal.GetReference(vectors.Slice(vectors.Length - 1)));
}
}
else
#endif
{
ref Vector4 baseRef = ref MemoryMarshal.GetReference(vectors);
for (int i = 0; i < vectors.Length; i++)
{
ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
Premultiply(ref v);
}
}
}
/// <summary>
/// Bulk variant of <see cref="UnPremultiply(ref Vector4)"/>
/// </summary>
/// <param name="vectors">The span of vectors</param>
[MethodImpl(InliningOptions.ShortMethod)]
public static void UnPremultiply(Span<Vector4> vectors)
{
#if SUPPORTS_RUNTIME_INTRINSICS
if (Avx2.IsSupported && vectors.Length >= 2)
{
ref Vector256<float> vectorsBase =
ref Unsafe.As<Vector4, Vector256<float>>(ref MemoryMarshal.GetReference(vectors));
// Divide by 2 as 4 elements per Vector4 and 8 per Vector256<float>
ref Vector256<float> vectorsLast = ref Unsafe.Add(ref vectorsBase, (IntPtr)((uint)vectors.Length / 2u));
while (Unsafe.IsAddressLessThan(ref vectorsBase, ref vectorsLast))
{
Vector256<float> source = vectorsBase;
Vector256<float> multiply = Avx.Shuffle(source, source, ShuffleAlphaControl);
vectorsBase = Avx.Blend(Avx.Divide(source, multiply), source, BlendAlphaControl);
vectorsBase = ref Unsafe.Add(ref vectorsBase, 1);
}
if (Numerics.Modulo2(vectors.Length) != 0)
{
// Vector4 fits neatly in pairs. Any overlap has to be equal to 1.
UnPremultiply(ref MemoryMarshal.GetReference(vectors.Slice(vectors.Length - 1)));
}
}
else
#endif
{
ref Vector4 baseRef = ref MemoryMarshal.GetReference(vectors);
for (int i = 0; i < vectors.Length; i++)
{
ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
UnPremultiply(ref v);
}
}
}
/// <summary>
/// Transforms a vector by the given matrix.
/// </summary>
/// <param name="vector">The source vector.</param>
/// <param name="matrix">The transformation matrix.</param>
[MethodImpl(InliningOptions.ShortMethod)]
public static void Transform(ref Vector4 vector, ref ColorMatrix matrix)
{
float x = vector.X;
float y = vector.Y;
float z = vector.Z;
float w = vector.W;
vector.X = (x * matrix.M11) + (y * matrix.M21) + (z * matrix.M31) + (w * matrix.M41) + matrix.M51;
vector.Y = (x * matrix.M12) + (y * matrix.M22) + (z * matrix.M32) + (w * matrix.M42) + matrix.M52;
vector.Z = (x * matrix.M13) + (y * matrix.M23) + (z * matrix.M33) + (w * matrix.M43) + matrix.M53;
vector.W = (x * matrix.M14) + (y * matrix.M24) + (z * matrix.M34) + (w * matrix.M44) + matrix.M54;
}
/// <summary>
/// Bulk variant of <see cref="Transform(ref Vector4, ref ColorMatrix)"/>.
/// </summary>
/// <param name="vectors">The span of vectors</param>
/// <param name="matrix">The transformation matrix.</param>
[MethodImpl(InliningOptions.ShortMethod)]
public static void Transform(Span<Vector4> vectors, ref ColorMatrix matrix)
{
ref Vector4 baseRef = ref MemoryMarshal.GetReference(vectors);
for (int i = 0; i < vectors.Length; i++)
{
ref Vector4 v = ref Unsafe.Add(ref baseRef, i);
Transform(ref v, ref matrix);
}
}
}
}

4
src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs

@ -1385,7 +1385,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
{
case BmpFileMarkerType.Bitmap:
colorMapSizeBytes = this.fileHeader.Offset - BmpFileHeader.Size - this.infoHeader.HeaderSize;
int colorCountForBitDepth = ImageMath.GetColorCountForBitDepth(this.infoHeader.BitsPerPixel);
int colorCountForBitDepth = ColorNumerics.GetColorCountForBitDepth(this.infoHeader.BitsPerPixel);
bytesPerColorMapEntry = colorMapSizeBytes / colorCountForBitDepth;
// Edge case for less-than-full-sized palette: bytesPerColorMapEntry should be at least 3.
@ -1399,7 +1399,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
case BmpFileMarkerType.Pointer:
// OS/2 bitmaps always have 3 colors per color palette entry.
bytesPerColorMapEntry = 3;
colorMapSizeBytes = ImageMath.GetColorCountForBitDepth(this.infoHeader.BitsPerPixel) * bytesPerColorMapEntry;
colorMapSizeBytes = ColorNumerics.GetColorCountForBitDepth(this.infoHeader.BitsPerPixel) * bytesPerColorMapEntry;
break;
}
}

6
src/ImageSharp/Formats/Gif/GifEncoderCore.cs

@ -105,7 +105,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
}
// Get the number of bits.
this.bitDepth = ImageMath.GetBitsNeededForColorDepth(quantized.Palette.Length);
this.bitDepth = ColorNumerics.GetBitsNeededForColorDepth(quantized.Palette.Length);
// Write the header.
this.WriteHeader(stream);
@ -212,7 +212,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
}
}
this.bitDepth = ImageMath.GetBitsNeededForColorDepth(quantized.Palette.Length);
this.bitDepth = ColorNumerics.GetBitsNeededForColorDepth(quantized.Palette.Length);
this.WriteGraphicalControlExtension(frameMetadata, this.GetTransparentIndex(quantized), stream);
this.WriteImageDescriptor(frame, true, stream);
this.WriteColorTable(quantized, stream);
@ -468,7 +468,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
where TPixel : unmanaged, IPixel<TPixel>
{
// The maximum number of colors for the bit depth
int colorTableLength = ImageMath.GetColorCountForBitDepth(this.bitDepth) * Unsafe.SizeOf<Rgb24>();
int colorTableLength = ColorNumerics.GetColorCountForBitDepth(this.bitDepth) * Unsafe.SizeOf<Rgb24>();
using IManagedByteBuffer colorTable = this.memoryAllocator.AllocateManagedByteBuffer(colorTableLength, AllocationOptions.Clean);
PixelOperations<TPixel>.Instance.ToRgb24Bytes(

6
src/ImageSharp/Formats/Png/PngEncoderCore.cs

@ -284,7 +284,7 @@ namespace SixLabors.ImageSharp.Formats.Png
rowSpan.Length,
AllocationOptions.Clean))
{
int scaleFactor = 255 / (ImageMath.GetColorCountForBitDepth(this.bitDepth) - 1);
int scaleFactor = 255 / (ColorNumerics.GetColorCountForBitDepth(this.bitDepth) - 1);
Span<byte> tempSpan = temp.GetSpan();
// We need to first create an array of luminance bytes then scale them down to the correct bit depth.
@ -314,7 +314,7 @@ namespace SixLabors.ImageSharp.Formats.Png
for (int x = 0, o = 0; x < rgbaSpan.Length; x++, o += 4)
{
Rgba64 rgba = Unsafe.Add(ref rgbaRef, x);
ushort luminance = ImageMath.Get16BitBT709Luminance(rgba.R, rgba.G, rgba.B);
ushort luminance = ColorNumerics.Get16BitBT709Luminance(rgba.R, rgba.G, rgba.B);
BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o, 2), luminance);
BinaryPrimitives.WriteUInt16BigEndian(rawScanlineSpan.Slice(o + 2, 2), rgba.A);
}
@ -329,7 +329,7 @@ namespace SixLabors.ImageSharp.Formats.Png
{
Unsafe.Add(ref rowSpanRef, x).ToRgba32(ref rgba);
Unsafe.Add(ref rawScanlineSpanRef, o) =
ImageMath.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
ColorNumerics.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
Unsafe.Add(ref rawScanlineSpanRef, o + 1) = rgba.A;
}
}

4
src/ImageSharp/Formats/Png/PngEncoderOptionsHelpers.cs

@ -75,7 +75,7 @@ namespace SixLabors.ImageSharp.Formats.Png
if (options.Quantizer is null)
{
byte bits = (byte)options.BitDepth;
var maxColors = ImageMath.GetColorCountForBitDepth(bits);
var maxColors = ColorNumerics.GetColorCountForBitDepth(bits);
options.Quantizer = new WuQuantizer(new QuantizerOptions { MaxColors = maxColors });
}
@ -101,7 +101,7 @@ namespace SixLabors.ImageSharp.Formats.Png
byte bitDepth;
if (options.ColorType == PngColorType.Palette)
{
byte quantizedBits = (byte)Numerics.Clamp(ImageMath.GetBitsNeededForColorDepth(quantizedFrame.Palette.Length), 1, 8);
byte quantizedBits = (byte)Numerics.Clamp(ColorNumerics.GetBitsNeededForColorDepth(quantizedFrame.Palette.Length), 1, 8);
byte bits = Math.Max((byte)options.BitDepth, quantizedBits);
// Png only supports in four pixel depths: 1, 2, 4, and 8 bits when using the PLTE chunk

4
src/ImageSharp/Formats/Png/PngScanlineProcessor.cs

@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Formats.Png
TPixel pixel = default;
ref byte scanlineSpanRef = ref MemoryMarshal.GetReference(scanlineSpan);
ref TPixel rowSpanRef = ref MemoryMarshal.GetReference(rowSpan);
int scaleFactor = 255 / (ImageMath.GetColorCountForBitDepth(header.BitDepth) - 1);
int scaleFactor = 255 / (ColorNumerics.GetColorCountForBitDepth(header.BitDepth) - 1);
if (!hasTrans)
{
@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.Formats.Png
TPixel pixel = default;
ref byte scanlineSpanRef = ref MemoryMarshal.GetReference(scanlineSpan);
ref TPixel rowSpanRef = ref MemoryMarshal.GetReference(rowSpan);
int scaleFactor = 255 / (ImageMath.GetColorCountForBitDepth(header.BitDepth) - 1);
int scaleFactor = 255 / (ColorNumerics.GetColorCountForBitDepth(header.BitDepth) - 1);
if (!hasTrans)
{

2
src/ImageSharp/Formats/Tga/TgaEncoderCore.cs

@ -365,7 +365,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
where TPixel : unmanaged, IPixel<TPixel>
{
var vector = sourcePixel.ToVector4();
return ImageMath.GetBT709Luminance(ref vector, 256);
return ColorNumerics.GetBT709Luminance(ref vector, 256);
}
}
}

2
src/ImageSharp/PixelFormats/PixelImplementations/A8.cs

@ -105,7 +105,7 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.PackedValue = ImageMath.DownScaleFrom16BitTo8Bit(source.A);
public void FromLa32(La32 source) => this.PackedValue = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]

20
src/ImageSharp/PixelFormats/PixelImplementations/Argb32.cs

@ -244,7 +244,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source)
{
byte rgb = ImageMath.DownScaleFrom16BitTo8Bit(source.PackedValue);
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue);
this.R = rgb;
this.G = rgb;
this.B = rgb;
@ -265,11 +265,11 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source)
{
byte rgb = ImageMath.DownScaleFrom16BitTo8Bit(source.L);
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L);
this.R = rgb;
this.G = rgb;
this.B = rgb;
this.A = ImageMath.DownScaleFrom16BitTo8Bit(source.A);
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
}
/// <inheritdoc/>
@ -306,9 +306,9 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
{
this.R = ImageMath.DownScaleFrom16BitTo8Bit(source.R);
this.G = ImageMath.DownScaleFrom16BitTo8Bit(source.G);
this.B = ImageMath.DownScaleFrom16BitTo8Bit(source.B);
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
this.A = byte.MaxValue;
}
@ -316,10 +316,10 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source)
{
this.R = ImageMath.DownScaleFrom16BitTo8Bit(source.R);
this.G = ImageMath.DownScaleFrom16BitTo8Bit(source.G);
this.B = ImageMath.DownScaleFrom16BitTo8Bit(source.B);
this.A = ImageMath.DownScaleFrom16BitTo8Bit(source.A);
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
}
/// <inheritdoc/>

16
src/ImageSharp/PixelFormats/PixelImplementations/Bgr24.cs

@ -151,7 +151,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source)
{
byte rgb = ImageMath.DownScaleFrom16BitTo8Bit(source.PackedValue);
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue);
this.R = rgb;
this.G = rgb;
this.B = rgb;
@ -170,7 +170,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source)
{
byte rgb = ImageMath.DownScaleFrom16BitTo8Bit(source.L);
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L);
this.R = rgb;
this.G = rgb;
this.B = rgb;
@ -203,18 +203,18 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
{
this.R = ImageMath.DownScaleFrom16BitTo8Bit(source.R);
this.G = ImageMath.DownScaleFrom16BitTo8Bit(source.G);
this.B = ImageMath.DownScaleFrom16BitTo8Bit(source.B);
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source)
{
this.R = ImageMath.DownScaleFrom16BitTo8Bit(source.R);
this.G = ImageMath.DownScaleFrom16BitTo8Bit(source.G);
this.B = ImageMath.DownScaleFrom16BitTo8Bit(source.B);
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
}
/// <inheritdoc/>

20
src/ImageSharp/PixelFormats/PixelImplementations/Bgra32.cs

@ -197,7 +197,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source)
{
byte rgb = ImageMath.DownScaleFrom16BitTo8Bit(source.PackedValue);
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue);
this.R = rgb;
this.G = rgb;
this.B = rgb;
@ -218,11 +218,11 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source)
{
byte rgb = ImageMath.DownScaleFrom16BitTo8Bit(source.L);
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L);
this.R = rgb;
this.G = rgb;
this.B = rgb;
this.A = ImageMath.DownScaleFrom16BitTo8Bit(source.A);
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
}
/// <inheritdoc/>
@ -259,9 +259,9 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
{
this.R = ImageMath.DownScaleFrom16BitTo8Bit(source.R);
this.G = ImageMath.DownScaleFrom16BitTo8Bit(source.G);
this.B = ImageMath.DownScaleFrom16BitTo8Bit(source.B);
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
this.A = byte.MaxValue;
}
@ -269,10 +269,10 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source)
{
this.R = ImageMath.DownScaleFrom16BitTo8Bit(source.R);
this.G = ImageMath.DownScaleFrom16BitTo8Bit(source.G);
this.B = ImageMath.DownScaleFrom16BitTo8Bit(source.B);
this.A = ImageMath.DownScaleFrom16BitTo8Bit(source.A);
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
}
/// <inheritdoc/>

52
src/ImageSharp/PixelFormats/PixelImplementations/L16.cs

@ -74,30 +74,30 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source)
{
this.PackedValue = ImageMath.Get16BitBT709Luminance(
ImageMath.UpscaleFrom8BitTo16Bit(source.R),
ImageMath.UpscaleFrom8BitTo16Bit(source.G),
ImageMath.UpscaleFrom8BitTo16Bit(source.B));
this.PackedValue = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source)
{
this.PackedValue = ImageMath.Get16BitBT709Luminance(
ImageMath.UpscaleFrom8BitTo16Bit(source.R),
ImageMath.UpscaleFrom8BitTo16Bit(source.G),
ImageMath.UpscaleFrom8BitTo16Bit(source.B));
this.PackedValue = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source)
{
this.PackedValue = ImageMath.Get16BitBT709Luminance(
ImageMath.UpscaleFrom8BitTo16Bit(source.R),
ImageMath.UpscaleFrom8BitTo16Bit(source.G),
ImageMath.UpscaleFrom8BitTo16Bit(source.B));
this.PackedValue = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
}
/// <inheritdoc/>
@ -106,7 +106,7 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source) => this.PackedValue = ImageMath.UpscaleFrom8BitTo16Bit(source.PackedValue);
public void FromL8(L8 source) => this.PackedValue = ColorNumerics.UpscaleFrom8BitTo16Bit(source.PackedValue);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
@ -114,7 +114,7 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source) => this.PackedValue = ImageMath.UpscaleFrom8BitTo16Bit(source.L);
public void FromLa16(La16 source) => this.PackedValue = ColorNumerics.UpscaleFrom8BitTo16Bit(source.L);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
@ -124,27 +124,27 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source)
{
this.PackedValue = ImageMath.Get16BitBT709Luminance(
ImageMath.UpscaleFrom8BitTo16Bit(source.R),
ImageMath.UpscaleFrom8BitTo16Bit(source.G),
ImageMath.UpscaleFrom8BitTo16Bit(source.B));
this.PackedValue = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source)
{
this.PackedValue = ImageMath.Get16BitBT709Luminance(
ImageMath.UpscaleFrom8BitTo16Bit(source.R),
ImageMath.UpscaleFrom8BitTo16Bit(source.G),
ImageMath.UpscaleFrom8BitTo16Bit(source.B));
this.PackedValue = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
byte rgb = ImageMath.DownScaleFrom16BitTo8Bit(this.PackedValue);
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(this.PackedValue);
dest.R = rgb;
dest.G = rgb;
dest.B = rgb;
@ -153,11 +153,11 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source) => this.PackedValue = ImageMath.Get16BitBT709Luminance(source.R, source.G, source.B);
public void FromRgb48(Rgb48 source) => this.PackedValue = ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source) => this.PackedValue = ImageMath.Get16BitBT709Luminance(source.R, source.G, source.B);
public void FromRgba64(Rgba64 source) => this.PackedValue = ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B);
/// <inheritdoc />
public override readonly bool Equals(object obj) => obj is L16 other && this.Equals(other);
@ -177,7 +177,7 @@ namespace SixLabors.ImageSharp.PixelFormats
internal void ConvertFromRgbaScaledVector4(Vector4 vector)
{
vector = Numerics.Clamp(vector, Vector4.Zero, Vector4.One) * Max;
this.PackedValue = ImageMath.Get16BitBT709Luminance(
this.PackedValue = ColorNumerics.Get16BitBT709Luminance(
vector.X,
vector.Y,
vector.Z);

32
src/ImageSharp/PixelFormats/PixelImplementations/L8.cs

@ -73,15 +73,15 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source) => this.PackedValue = ImageMath.Get8BitBT709Luminance(source.R, source.G, source.B);
public void FromArgb32(Argb32 source) => this.PackedValue = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source) => this.PackedValue = ImageMath.Get8BitBT709Luminance(source.R, source.G, source.B);
public void FromBgr24(Bgr24 source) => this.PackedValue = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.PackedValue = ImageMath.Get8BitBT709Luminance(source.R, source.G, source.B);
public void FromBgra32(Bgra32 source) => this.PackedValue = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
@ -93,7 +93,7 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source) => this.PackedValue = ImageMath.DownScaleFrom16BitTo8Bit(source.PackedValue);
public void FromL16(L16 source) => this.PackedValue = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
@ -101,15 +101,15 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source) => this.PackedValue = ImageMath.DownScaleFrom16BitTo8Bit(source.L);
public void FromLa32(La32 source) => this.PackedValue = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L);
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source) => this.PackedValue = ImageMath.Get8BitBT709Luminance(source.R, source.G, source.B);
public void FromRgb24(Rgb24 source) => this.PackedValue = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source) => this.PackedValue = ImageMath.Get8BitBT709Luminance(source.R, source.G, source.B);
public void FromRgba32(Rgba32 source) => this.PackedValue = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
@ -124,18 +124,18 @@ namespace SixLabors.ImageSharp.PixelFormats
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
=> this.PackedValue = ImageMath.Get8BitBT709Luminance(
ImageMath.DownScaleFrom16BitTo8Bit(source.R),
ImageMath.DownScaleFrom16BitTo8Bit(source.G),
ImageMath.DownScaleFrom16BitTo8Bit(source.B));
=> this.PackedValue = ColorNumerics.Get8BitBT709Luminance(
ColorNumerics.DownScaleFrom16BitTo8Bit(source.R),
ColorNumerics.DownScaleFrom16BitTo8Bit(source.G),
ColorNumerics.DownScaleFrom16BitTo8Bit(source.B));
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source)
=> this.PackedValue = ImageMath.Get8BitBT709Luminance(
ImageMath.DownScaleFrom16BitTo8Bit(source.R),
ImageMath.DownScaleFrom16BitTo8Bit(source.G),
ImageMath.DownScaleFrom16BitTo8Bit(source.B));
=> this.PackedValue = ColorNumerics.Get8BitBT709Luminance(
ColorNumerics.DownScaleFrom16BitTo8Bit(source.R),
ColorNumerics.DownScaleFrom16BitTo8Bit(source.G),
ColorNumerics.DownScaleFrom16BitTo8Bit(source.B));
/// <inheritdoc />
public override readonly bool Equals(object obj) => obj is L8 other && this.Equals(other);
@ -157,7 +157,7 @@ namespace SixLabors.ImageSharp.PixelFormats
vector *= MaxBytes;
vector += Half;
vector = Numerics.Clamp(vector, Vector4.Zero, MaxBytes);
this.PackedValue = ImageMath.Get8BitBT709Luminance((byte)vector.X, (byte)vector.Y, (byte)vector.Z);
this.PackedValue = ColorNumerics.Get8BitBT709Luminance((byte)vector.X, (byte)vector.Y, (byte)vector.Z);
}
}
}

36
src/ImageSharp/PixelFormats/PixelImplementations/La16.cs

@ -92,7 +92,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source)
{
this.L = ImageMath.Get8BitBT709Luminance(source.R, source.G, source.B);
this.L = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
this.A = source.A;
}
@ -100,7 +100,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source)
{
this.L = ImageMath.Get8BitBT709Luminance(source.R, source.G, source.B);
this.L = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
this.A = byte.MaxValue;
}
@ -108,7 +108,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source)
{
this.L = ImageMath.Get8BitBT709Luminance(source.R, source.G, source.B);
this.L = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
this.A = source.A;
}
@ -120,7 +120,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source)
{
this.L = ImageMath.DownScaleFrom16BitTo8Bit(source.PackedValue);
this.L = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue);
this.A = byte.MaxValue;
}
@ -140,15 +140,15 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source)
{
this.L = ImageMath.DownScaleFrom16BitTo8Bit(source.L);
this.A = ImageMath.DownScaleFrom16BitTo8Bit(source.A);
this.L = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L);
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source)
{
this.L = ImageMath.Get8BitBT709Luminance(source.R, source.G, source.B);
this.L = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
this.A = byte.MaxValue;
}
@ -156,10 +156,10 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
{
this.L = ImageMath.Get8BitBT709Luminance(
ImageMath.DownScaleFrom16BitTo8Bit(source.R),
ImageMath.DownScaleFrom16BitTo8Bit(source.G),
ImageMath.DownScaleFrom16BitTo8Bit(source.B));
this.L = ColorNumerics.Get8BitBT709Luminance(
ColorNumerics.DownScaleFrom16BitTo8Bit(source.R),
ColorNumerics.DownScaleFrom16BitTo8Bit(source.G),
ColorNumerics.DownScaleFrom16BitTo8Bit(source.B));
this.A = byte.MaxValue;
}
@ -168,19 +168,19 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source)
{
this.L = ImageMath.Get8BitBT709Luminance(source.R, source.G, source.B);
this.L = ColorNumerics.Get8BitBT709Luminance(source.R, source.G, source.B);
this.A = source.A;
}
/// <inheritdoc/>
public void FromRgba64(Rgba64 source)
{
this.L = ImageMath.Get8BitBT709Luminance(
ImageMath.DownScaleFrom16BitTo8Bit(source.R),
ImageMath.DownScaleFrom16BitTo8Bit(source.G),
ImageMath.DownScaleFrom16BitTo8Bit(source.B));
this.L = ColorNumerics.Get8BitBT709Luminance(
ColorNumerics.DownScaleFrom16BitTo8Bit(source.R),
ColorNumerics.DownScaleFrom16BitTo8Bit(source.G),
ColorNumerics.DownScaleFrom16BitTo8Bit(source.B));
this.A = ImageMath.DownScaleFrom16BitTo8Bit(source.A);
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
}
/// <inheritdoc/>
@ -220,7 +220,7 @@ namespace SixLabors.ImageSharp.PixelFormats
vector *= MaxBytes;
vector += Half;
vector = Numerics.Clamp(vector, Vector4.Zero, MaxBytes);
this.L = ImageMath.Get8BitBT709Luminance((byte)vector.X, (byte)vector.Y, (byte)vector.Z);
this.L = ColorNumerics.Get8BitBT709Luminance((byte)vector.X, (byte)vector.Y, (byte)vector.Z);
this.A = (byte)vector.W;
}
}

62
src/ImageSharp/PixelFormats/PixelImplementations/La32.cs

@ -95,22 +95,22 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source)
{
this.L = ImageMath.Get16BitBT709Luminance(
ImageMath.UpscaleFrom8BitTo16Bit(source.R),
ImageMath.UpscaleFrom8BitTo16Bit(source.G),
ImageMath.UpscaleFrom8BitTo16Bit(source.B));
this.L = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
this.A = ImageMath.UpscaleFrom8BitTo16Bit(source.A);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source)
{
this.L = ImageMath.Get16BitBT709Luminance(
ImageMath.UpscaleFrom8BitTo16Bit(source.R),
ImageMath.UpscaleFrom8BitTo16Bit(source.G),
ImageMath.UpscaleFrom8BitTo16Bit(source.B));
this.L = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
this.A = ushort.MaxValue;
}
@ -119,12 +119,12 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source)
{
this.L = ImageMath.Get16BitBT709Luminance(
ImageMath.UpscaleFrom8BitTo16Bit(source.R),
ImageMath.UpscaleFrom8BitTo16Bit(source.G),
ImageMath.UpscaleFrom8BitTo16Bit(source.B));
this.L = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
this.A = ImageMath.UpscaleFrom8BitTo16Bit(source.A);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
}
/// <inheritdoc/>
@ -143,7 +143,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source)
{
this.L = ImageMath.UpscaleFrom8BitTo16Bit(source.PackedValue);
this.L = ColorNumerics.UpscaleFrom8BitTo16Bit(source.PackedValue);
this.A = ushort.MaxValue;
}
@ -151,8 +151,8 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source)
{
this.L = ImageMath.UpscaleFrom8BitTo16Bit(source.L);
this.A = ImageMath.UpscaleFrom8BitTo16Bit(source.A);
this.L = ColorNumerics.UpscaleFrom8BitTo16Bit(source.L);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
}
/// <inheritdoc/>
@ -163,10 +163,10 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source)
{
this.L = ImageMath.Get16BitBT709Luminance(
ImageMath.UpscaleFrom8BitTo16Bit(source.R),
ImageMath.UpscaleFrom8BitTo16Bit(source.G),
ImageMath.UpscaleFrom8BitTo16Bit(source.B));
this.L = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
this.A = ushort.MaxValue;
}
@ -175,7 +175,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
{
this.L = ImageMath.Get16BitBT709Luminance(source.R, source.G, source.B);
this.L = ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B);
this.A = ushort.MaxValue;
}
@ -183,19 +183,19 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source)
{
this.L = ImageMath.Get16BitBT709Luminance(
ImageMath.UpscaleFrom8BitTo16Bit(source.R),
ImageMath.UpscaleFrom8BitTo16Bit(source.G),
ImageMath.UpscaleFrom8BitTo16Bit(source.B));
this.L = ColorNumerics.Get16BitBT709Luminance(
ColorNumerics.UpscaleFrom8BitTo16Bit(source.R),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.G),
ColorNumerics.UpscaleFrom8BitTo16Bit(source.B));
this.A = ImageMath.UpscaleFrom8BitTo16Bit(source.A);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source)
{
this.L = ImageMath.Get16BitBT709Luminance(source.R, source.G, source.B);
this.L = ColorNumerics.Get16BitBT709Luminance(source.R, source.G, source.B);
this.A = source.A;
}
@ -211,11 +211,11 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
byte rgb = ImageMath.DownScaleFrom16BitTo8Bit(this.L);
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(this.L);
dest.R = rgb;
dest.G = rgb;
dest.B = rgb;
dest.A = ImageMath.DownScaleFrom16BitTo8Bit(this.A);
dest.A = ColorNumerics.DownScaleFrom16BitTo8Bit(this.A);
}
/// <inheritdoc/>
@ -234,7 +234,7 @@ namespace SixLabors.ImageSharp.PixelFormats
internal void ConvertFromRgbaScaledVector4(Vector4 vector)
{
vector = Numerics.Clamp(vector, Vector4.Zero, Vector4.One) * Max;
this.L = ImageMath.Get16BitBT709Luminance(
this.L = ColorNumerics.Get16BitBT709Luminance(
vector.X,
vector.Y,
vector.Z);

16
src/ImageSharp/PixelFormats/PixelImplementations/Rgb24.cs

@ -166,7 +166,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source)
{
byte rgb = ImageMath.DownScaleFrom16BitTo8Bit(source.PackedValue);
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue);
this.R = rgb;
this.G = rgb;
this.B = rgb;
@ -185,7 +185,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source)
{
byte rgb = ImageMath.DownScaleFrom16BitTo8Bit(source.L);
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L);
this.R = rgb;
this.G = rgb;
this.B = rgb;
@ -227,18 +227,18 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
{
this.R = ImageMath.DownScaleFrom16BitTo8Bit(source.R);
this.G = ImageMath.DownScaleFrom16BitTo8Bit(source.G);
this.B = ImageMath.DownScaleFrom16BitTo8Bit(source.B);
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
}
/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source)
{
this.R = ImageMath.DownScaleFrom16BitTo8Bit(source.R);
this.G = ImageMath.DownScaleFrom16BitTo8Bit(source.G);
this.B = ImageMath.DownScaleFrom16BitTo8Bit(source.B);
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
}
/// <inheritdoc/>

40
src/ImageSharp/PixelFormats/PixelImplementations/Rgb48.cs

@ -99,27 +99,27 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source)
{
this.R = ImageMath.UpscaleFrom8BitTo16Bit(source.R);
this.G = ImageMath.UpscaleFrom8BitTo16Bit(source.G);
this.B = ImageMath.UpscaleFrom8BitTo16Bit(source.B);
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source)
{
this.R = ImageMath.UpscaleFrom8BitTo16Bit(source.R);
this.G = ImageMath.UpscaleFrom8BitTo16Bit(source.G);
this.B = ImageMath.UpscaleFrom8BitTo16Bit(source.B);
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source)
{
this.R = ImageMath.UpscaleFrom8BitTo16Bit(source.R);
this.G = ImageMath.UpscaleFrom8BitTo16Bit(source.G);
this.B = ImageMath.UpscaleFrom8BitTo16Bit(source.B);
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
}
/// <inheritdoc/>
@ -134,7 +134,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source)
{
ushort rgb = ImageMath.UpscaleFrom8BitTo16Bit(source.PackedValue);
ushort rgb = ColorNumerics.UpscaleFrom8BitTo16Bit(source.PackedValue);
this.R = rgb;
this.G = rgb;
this.B = rgb;
@ -153,7 +153,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source)
{
ushort rgb = ImageMath.UpscaleFrom8BitTo16Bit(source.L);
ushort rgb = ColorNumerics.UpscaleFrom8BitTo16Bit(source.L);
this.R = rgb;
this.G = rgb;
this.B = rgb;
@ -172,27 +172,27 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source)
{
this.R = ImageMath.UpscaleFrom8BitTo16Bit(source.R);
this.G = ImageMath.UpscaleFrom8BitTo16Bit(source.G);
this.B = ImageMath.UpscaleFrom8BitTo16Bit(source.B);
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source)
{
this.R = ImageMath.UpscaleFrom8BitTo16Bit(source.R);
this.G = ImageMath.UpscaleFrom8BitTo16Bit(source.G);
this.B = ImageMath.UpscaleFrom8BitTo16Bit(source.B);
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
dest.R = ImageMath.DownScaleFrom16BitTo8Bit(this.R);
dest.G = ImageMath.DownScaleFrom16BitTo8Bit(this.G);
dest.B = ImageMath.DownScaleFrom16BitTo8Bit(this.B);
dest.R = ColorNumerics.DownScaleFrom16BitTo8Bit(this.R);
dest.G = ColorNumerics.DownScaleFrom16BitTo8Bit(this.G);
dest.B = ColorNumerics.DownScaleFrom16BitTo8Bit(this.B);
dest.A = byte.MaxValue;
}

20
src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs

@ -351,7 +351,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL16(L16 source)
{
byte rgb = ImageMath.DownScaleFrom16BitTo8Bit(source.PackedValue);
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.PackedValue);
this.R = rgb;
this.G = rgb;
this.B = rgb;
@ -372,11 +372,11 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa32(La32 source)
{
byte rgb = ImageMath.DownScaleFrom16BitTo8Bit(source.L);
byte rgb = ColorNumerics.DownScaleFrom16BitTo8Bit(source.L);
this.R = rgb;
this.G = rgb;
this.B = rgb;
this.A = ImageMath.DownScaleFrom16BitTo8Bit(source.A);
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
}
/// <inheritdoc/>
@ -402,9 +402,9 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb48(Rgb48 source)
{
this.R = ImageMath.DownScaleFrom16BitTo8Bit(source.R);
this.G = ImageMath.DownScaleFrom16BitTo8Bit(source.G);
this.B = ImageMath.DownScaleFrom16BitTo8Bit(source.B);
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
this.A = byte.MaxValue;
}
@ -412,10 +412,10 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba64(Rgba64 source)
{
this.R = ImageMath.DownScaleFrom16BitTo8Bit(source.R);
this.G = ImageMath.DownScaleFrom16BitTo8Bit(source.G);
this.B = ImageMath.DownScaleFrom16BitTo8Bit(source.B);
this.A = ImageMath.DownScaleFrom16BitTo8Bit(source.A);
this.R = ColorNumerics.DownScaleFrom16BitTo8Bit(source.R);
this.G = ColorNumerics.DownScaleFrom16BitTo8Bit(source.G);
this.B = ColorNumerics.DownScaleFrom16BitTo8Bit(source.B);
this.A = ColorNumerics.DownScaleFrom16BitTo8Bit(source.A);
}
/// <summary>

122
src/ImageSharp/PixelFormats/PixelImplementations/Rgba64.cs

@ -62,10 +62,10 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public Rgba64(Rgba32 source)
{
this.R = ImageMath.UpscaleFrom8BitTo16Bit(source.R);
this.G = ImageMath.UpscaleFrom8BitTo16Bit(source.G);
this.B = ImageMath.UpscaleFrom8BitTo16Bit(source.B);
this.A = ImageMath.UpscaleFrom8BitTo16Bit(source.A);
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
}
/// <summary>
@ -75,10 +75,10 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public Rgba64(Bgra32 source)
{
this.R = ImageMath.UpscaleFrom8BitTo16Bit(source.R);
this.G = ImageMath.UpscaleFrom8BitTo16Bit(source.G);
this.B = ImageMath.UpscaleFrom8BitTo16Bit(source.B);
this.A = ImageMath.UpscaleFrom8BitTo16Bit(source.A);
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
}
/// <summary>
@ -88,10 +88,10 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public Rgba64(Argb32 source)
{
this.R = ImageMath.UpscaleFrom8BitTo16Bit(source.R);
this.G = ImageMath.UpscaleFrom8BitTo16Bit(source.G);
this.B = ImageMath.UpscaleFrom8BitTo16Bit(source.B);
this.A = ImageMath.UpscaleFrom8BitTo16Bit(source.A);
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
}
/// <summary>
@ -101,9 +101,9 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public Rgba64(Rgb24 source)
{
this.R = ImageMath.UpscaleFrom8BitTo16Bit(source.R);
this.G = ImageMath.UpscaleFrom8BitTo16Bit(source.G);
this.B = ImageMath.UpscaleFrom8BitTo16Bit(source.B);
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ushort.MaxValue;
}
@ -114,9 +114,9 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public Rgba64(Bgr24 source)
{
this.R = ImageMath.UpscaleFrom8BitTo16Bit(source.R);
this.G = ImageMath.UpscaleFrom8BitTo16Bit(source.G);
this.B = ImageMath.UpscaleFrom8BitTo16Bit(source.B);
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ushort.MaxValue;
}
@ -224,19 +224,19 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromArgb32(Argb32 source)
{
this.R = ImageMath.UpscaleFrom8BitTo16Bit(source.R);
this.G = ImageMath.UpscaleFrom8BitTo16Bit(source.G);
this.B = ImageMath.UpscaleFrom8BitTo16Bit(source.B);
this.A = ImageMath.UpscaleFrom8BitTo16Bit(source.A);
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgr24(Bgr24 source)
{
this.R = ImageMath.UpscaleFrom8BitTo16Bit(source.R);
this.G = ImageMath.UpscaleFrom8BitTo16Bit(source.G);
this.B = ImageMath.UpscaleFrom8BitTo16Bit(source.B);
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ushort.MaxValue;
}
@ -244,10 +244,10 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source)
{
this.R = ImageMath.UpscaleFrom8BitTo16Bit(source.R);
this.G = ImageMath.UpscaleFrom8BitTo16Bit(source.G);
this.B = ImageMath.UpscaleFrom8BitTo16Bit(source.B);
this.A = ImageMath.UpscaleFrom8BitTo16Bit(source.A);
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
}
/// <inheritdoc/>
@ -258,7 +258,7 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromL8(L8 source)
{
ushort rgb = ImageMath.UpscaleFrom8BitTo16Bit(source.PackedValue);
ushort rgb = ColorNumerics.UpscaleFrom8BitTo16Bit(source.PackedValue);
this.R = rgb;
this.G = rgb;
this.B = rgb;
@ -279,11 +279,11 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromLa16(La16 source)
{
ushort rgb = ImageMath.UpscaleFrom8BitTo16Bit(source.L);
ushort rgb = ColorNumerics.UpscaleFrom8BitTo16Bit(source.L);
this.R = rgb;
this.G = rgb;
this.B = rgb;
this.A = ImageMath.UpscaleFrom8BitTo16Bit(source.A);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
}
/// <inheritdoc/>
@ -300,9 +300,9 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgb24(Rgb24 source)
{
this.R = ImageMath.UpscaleFrom8BitTo16Bit(source.R);
this.G = ImageMath.UpscaleFrom8BitTo16Bit(source.G);
this.B = ImageMath.UpscaleFrom8BitTo16Bit(source.B);
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ushort.MaxValue;
}
@ -310,20 +310,20 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public void FromRgba32(Rgba32 source)
{
this.R = ImageMath.UpscaleFrom8BitTo16Bit(source.R);
this.G = ImageMath.UpscaleFrom8BitTo16Bit(source.G);
this.B = ImageMath.UpscaleFrom8BitTo16Bit(source.B);
this.A = ImageMath.UpscaleFrom8BitTo16Bit(source.A);
this.R = ColorNumerics.UpscaleFrom8BitTo16Bit(source.R);
this.G = ColorNumerics.UpscaleFrom8BitTo16Bit(source.G);
this.B = ColorNumerics.UpscaleFrom8BitTo16Bit(source.B);
this.A = ColorNumerics.UpscaleFrom8BitTo16Bit(source.A);
}
/// <inheritdoc />
[MethodImpl(InliningOptions.ShortMethod)]
public void ToRgba32(ref Rgba32 dest)
{
dest.R = ImageMath.DownScaleFrom16BitTo8Bit(this.R);
dest.G = ImageMath.DownScaleFrom16BitTo8Bit(this.G);
dest.B = ImageMath.DownScaleFrom16BitTo8Bit(this.B);
dest.A = ImageMath.DownScaleFrom16BitTo8Bit(this.A);
dest.R = ColorNumerics.DownScaleFrom16BitTo8Bit(this.R);
dest.G = ColorNumerics.DownScaleFrom16BitTo8Bit(this.G);
dest.B = ColorNumerics.DownScaleFrom16BitTo8Bit(this.B);
dest.A = ColorNumerics.DownScaleFrom16BitTo8Bit(this.A);
}
/// <inheritdoc/>
@ -345,10 +345,10 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Rgba32 ToRgba32()
{
byte r = ImageMath.DownScaleFrom16BitTo8Bit(this.R);
byte g = ImageMath.DownScaleFrom16BitTo8Bit(this.G);
byte b = ImageMath.DownScaleFrom16BitTo8Bit(this.B);
byte a = ImageMath.DownScaleFrom16BitTo8Bit(this.A);
byte r = ColorNumerics.DownScaleFrom16BitTo8Bit(this.R);
byte g = ColorNumerics.DownScaleFrom16BitTo8Bit(this.G);
byte b = ColorNumerics.DownScaleFrom16BitTo8Bit(this.B);
byte a = ColorNumerics.DownScaleFrom16BitTo8Bit(this.A);
return new Rgba32(r, g, b, a);
}
@ -359,10 +359,10 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Bgra32 ToBgra32()
{
byte r = ImageMath.DownScaleFrom16BitTo8Bit(this.R);
byte g = ImageMath.DownScaleFrom16BitTo8Bit(this.G);
byte b = ImageMath.DownScaleFrom16BitTo8Bit(this.B);
byte a = ImageMath.DownScaleFrom16BitTo8Bit(this.A);
byte r = ColorNumerics.DownScaleFrom16BitTo8Bit(this.R);
byte g = ColorNumerics.DownScaleFrom16BitTo8Bit(this.G);
byte b = ColorNumerics.DownScaleFrom16BitTo8Bit(this.B);
byte a = ColorNumerics.DownScaleFrom16BitTo8Bit(this.A);
return new Bgra32(r, g, b, a);
}
@ -373,10 +373,10 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Argb32 ToArgb32()
{
byte r = ImageMath.DownScaleFrom16BitTo8Bit(this.R);
byte g = ImageMath.DownScaleFrom16BitTo8Bit(this.G);
byte b = ImageMath.DownScaleFrom16BitTo8Bit(this.B);
byte a = ImageMath.DownScaleFrom16BitTo8Bit(this.A);
byte r = ColorNumerics.DownScaleFrom16BitTo8Bit(this.R);
byte g = ColorNumerics.DownScaleFrom16BitTo8Bit(this.G);
byte b = ColorNumerics.DownScaleFrom16BitTo8Bit(this.B);
byte a = ColorNumerics.DownScaleFrom16BitTo8Bit(this.A);
return new Argb32(r, g, b, a);
}
@ -387,9 +387,9 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Rgb24 ToRgb24()
{
byte r = ImageMath.DownScaleFrom16BitTo8Bit(this.R);
byte g = ImageMath.DownScaleFrom16BitTo8Bit(this.G);
byte b = ImageMath.DownScaleFrom16BitTo8Bit(this.B);
byte r = ColorNumerics.DownScaleFrom16BitTo8Bit(this.R);
byte g = ColorNumerics.DownScaleFrom16BitTo8Bit(this.G);
byte b = ColorNumerics.DownScaleFrom16BitTo8Bit(this.B);
return new Rgb24(r, g, b);
}
@ -400,9 +400,9 @@ namespace SixLabors.ImageSharp.PixelFormats
[MethodImpl(InliningOptions.ShortMethod)]
public readonly Bgr24 ToBgr24()
{
byte r = ImageMath.DownScaleFrom16BitTo8Bit(this.R);
byte g = ImageMath.DownScaleFrom16BitTo8Bit(this.G);
byte b = ImageMath.DownScaleFrom16BitTo8Bit(this.B);
byte r = ColorNumerics.DownScaleFrom16BitTo8Bit(this.R);
byte g = ColorNumerics.DownScaleFrom16BitTo8Bit(this.G);
byte b = ColorNumerics.DownScaleFrom16BitTo8Bit(this.B);
return new Bgr24(r, g, b);
}

4
src/ImageSharp/PixelFormats/Utils/Vector4Converters.cs

@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils
if (modifiers.IsDefined(PixelConversionModifiers.Premultiply))
{
Vector4Utils.Premultiply(vectors);
Numerics.Premultiply(vectors);
}
}
@ -36,7 +36,7 @@ namespace SixLabors.ImageSharp.PixelFormats.Utils
{
if (modifiers.IsDefined(PixelConversionModifiers.Premultiply))
{
Vector4Utils.UnPremultiply(vectors);
Numerics.UnPremultiply(vectors);
}
if (modifiers.IsDefined(PixelConversionModifiers.SRgbCompand))

2
src/ImageSharp/Processing/Processors/Binarization/BinaryThresholdProcessor{TPixel}.cs

@ -96,7 +96,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Binarization
color.ToRgba32(ref rgba);
// Convert to grayscale using ITU-R Recommendation BT.709 if required
byte luminance = this.isAlphaOnly ? rgba.A : ImageMath.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
byte luminance = this.isAlphaOnly ? rgba.A : ColorNumerics.Get8BitBT709Luminance(rgba.R, rgba.G, rgba.B);
color = luminance >= this.threshold ? this.upper : this.lower;
}
}

4
src/ImageSharp/Processing/Processors/Dithering/OrderedDither.cs

@ -218,7 +218,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering
this.source = source;
this.destination = destination;
this.bounds = bounds;
this.bitDepth = ImageMath.GetBitsNeededForColorDepth(destination.Palette.Length);
this.bitDepth = ColorNumerics.GetBitsNeededForColorDepth(destination.Palette.Length);
}
[MethodImpl(InliningOptions.ShortMethod)]
@ -262,7 +262,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Dithering
this.source = source;
this.bounds = bounds;
this.scale = processor.DitherScale;
this.bitDepth = ImageMath.GetBitsNeededForColorDepth(processor.Palette.Length);
this.bitDepth = ColorNumerics.GetBitsNeededForColorDepth(processor.Palette.Length);
}
[MethodImpl(InliningOptions.ShortMethod)]

2
src/ImageSharp/Processing/Processors/Filters/FilterProcessor{TPixel}.cs

@ -74,7 +74,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Filters
Span<TPixel> rowSpan = this.source.GetPixelRowSpan(y).Slice(this.startX, span.Length);
PixelOperations<TPixel>.Instance.ToVector4(this.configuration, rowSpan, span);
Vector4Utils.Transform(span, ref Unsafe.AsRef(this.matrix));
ColorNumerics.Transform(span, ref Unsafe.AsRef(this.matrix));
PixelOperations<TPixel>.Instance.FromVector4Destructive(this.configuration, span, rowSpan);
}

4
src/ImageSharp/Processing/Processors/Normalization/AdaptiveHistogramEqualizationSlidingWindowProcessor{TPixel}.cs

@ -259,7 +259,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
{
for (int idx = 0; idx < length; idx++)
{
int luminance = ImageMath.GetBT709Luminance(ref Unsafe.Add(ref greyValuesBase, idx), luminanceLevels);
int luminance = ColorNumerics.GetBT709Luminance(ref Unsafe.Add(ref greyValuesBase, idx), luminanceLevels);
Unsafe.Add(ref histogramBase, luminance)++;
}
}
@ -276,7 +276,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
{
for (int idx = 0; idx < length; idx++)
{
int luminance = ImageMath.GetBT709Luminance(ref Unsafe.Add(ref greyValuesBase, idx), luminanceLevels);
int luminance = ColorNumerics.GetBT709Luminance(ref Unsafe.Add(ref greyValuesBase, idx), luminanceLevels);
Unsafe.Add(ref histogramBase, luminance)--;
}
}

4
src/ImageSharp/Processing/Processors/Normalization/GlobalHistogramEqualizationProcessor{TPixel}.cs

@ -123,7 +123,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
{
// TODO: We should bulk convert here.
var vector = pixelRow[x].ToVector4();
int luminance = ImageMath.GetBT709Luminance(ref vector, levels);
int luminance = ColorNumerics.GetBT709Luminance(ref vector, levels);
Interlocked.Increment(ref Unsafe.Add(ref histogramBase, luminance));
}
}
@ -174,7 +174,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
// TODO: We should bulk convert here.
ref TPixel pixel = ref pixelRow[x];
var vector = pixel.ToVector4();
int luminance = ImageMath.GetBT709Luminance(ref vector, levels);
int luminance = ColorNumerics.GetBT709Luminance(ref vector, levels);
float luminanceEqualized = Unsafe.Add(ref cdfBase, luminance) / noOfPixelsMinusCdfMin;
pixel.FromVector4(new Vector4(luminanceEqualized, luminanceEqualized, luminanceEqualized, vector.W));
}

2
src/ImageSharp/Processing/Processors/Normalization/HistogramEqualizationProcessor{TPixel}.cs

@ -143,7 +143,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Normalization
public static int GetLuminance(TPixel sourcePixel, int luminanceLevels)
{
var vector = sourcePixel.ToVector4();
return ImageMath.GetBT709Luminance(ref vector, luminanceLevels);
return ColorNumerics.GetBT709Luminance(ref vector, luminanceLevels);
}
}
}

2
src/ImageSharp/Processing/Processors/Quantization/OctreeQuantizer{TPixel}.cs

@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Quantization
this.Options = options;
this.maxColors = this.Options.MaxColors;
this.octree = new Octree(Numerics.Clamp(ImageMath.GetBitsNeededForColorDepth(this.maxColors), 1, 8));
this.octree = new Octree(Numerics.Clamp(ColorNumerics.GetBitsNeededForColorDepth(this.maxColors), 1, 8));
this.paletteOwner = configuration.MemoryAllocator.Allocate<TPixel>(this.maxColors, AllocationOptions.Clean);
this.palette = default;
this.pixelMap = default;

135
src/ImageSharp/Processing/Processors/Transforms/EntropyCropProcessor{TPixel}.cs

@ -1,6 +1,8 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing.Processors.Binarization;
@ -48,7 +50,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
new BinaryThresholdProcessor(this.definition.Threshold).Execute(this.Configuration, temp, this.SourceRectangle);
// Search for the first white pixels
rectangle = ImageMath.GetFilteredBoundingRectangle(temp.Frames.RootFrame, 0);
rectangle = GetFilteredBoundingRectangle(temp.Frames.RootFrame, 0);
}
new CropProcessor(rectangle, this.Source.Size()).Execute(this.Configuration, this.Source, this.SourceRectangle);
@ -61,5 +63,136 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
{
// All processing happens at the image level within BeforeImageApply();
}
/// <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>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Rectangle GetBoundingRectangle(Point topLeft, Point bottomRight)
=> new Rectangle(
topLeft.X,
topLeft.Y,
bottomRight.X - topLeft.X,
bottomRight.Y - topLeft.Y);
/// <summary>
/// Finds the bounding rectangle based on the first instance of any color component other
/// than the given one.
/// </summary>
/// <param name="bitmap">The <see cref="Image{TPixel}"/> 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>
private static Rectangle GetFilteredBoundingRectangle(ImageFrame<TPixel> bitmap, float componentValue, RgbaComponent channel = RgbaComponent.B)
{
int width = bitmap.Width;
int height = bitmap.Height;
Point topLeft = default;
Point bottomRight = default;
Func<ImageFrame<TPixel>, int, int, float, bool> delegateFunc;
// Determine which channel to check against
switch (channel)
{
case RgbaComponent.R:
delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().X - b) > Constants.Epsilon;
break;
case RgbaComponent.G:
delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().Y - b) > Constants.Epsilon;
break;
case RgbaComponent.B:
delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().Z - b) > Constants.Epsilon;
break;
default:
delegateFunc = (pixels, x, y, b) => MathF.Abs(pixels[x, y].ToVector4().W - b) > Constants.Epsilon;
break;
}
int GetMinY(ImageFrame<TPixel> 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;
}
int GetMaxY(ImageFrame<TPixel> 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;
}
int GetMinX(ImageFrame<TPixel> 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;
}
int GetMaxX(ImageFrame<TPixel> 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 width;
}
topLeft.Y = GetMinY(bitmap);
topLeft.X = GetMinX(bitmap);
bottomRight.Y = Numerics.Clamp(GetMaxY(bitmap) + 1, 0, height);
bottomRight.X = Numerics.Clamp(GetMaxX(bitmap) + 1, 0, width);
return GetBoundingRectangle(topLeft, bottomRight);
}
}
}

4
src/ImageSharp/Processing/Processors/Transforms/Linear/LinearTransformUtils.cs

@ -78,13 +78,13 @@ namespace SixLabors.ImageSharp.Processing.Processors.Transforms
// Values are first premultiplied to prevent darkening of edge pixels.
var current = sourcePixels[x, y].ToVector4();
Vector4Utils.Premultiply(ref current);
Numerics.Premultiply(ref current);
sum += current * xWeight * yWeight;
}
}
// Reverse the premultiplication
Vector4Utils.UnPremultiply(ref sum);
Numerics.UnPremultiply(ref sum);
targetRow[column] = sum;
}

2
tests/ImageSharp.Benchmarks/Color/Bulk/PremultiplyVector4.cs

@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk
[Benchmark]
public void Premultiply()
{
Vector4Utils.Premultiply(Vectors);
Numerics.Premultiply(Vectors);
}
[MethodImpl(InliningOptions.ShortMethod)]

2
tests/ImageSharp.Benchmarks/Color/Bulk/UnPremultiplyVector4.cs

@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Benchmarks.ColorSpaces.Bulk
[Benchmark]
public void UnPremultiply()
{
Vector4Utils.UnPremultiply(Vectors);
Numerics.UnPremultiply(Vectors);
}
[MethodImpl(InliningOptions.ShortMethod)]

2
tests/ImageSharp.Tests/Formats/Png/PngEncoderTests.cs

@ -435,7 +435,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Png
Rgba32 expectedColor = Color.Blue;
if (colorType == PngColorType.Grayscale || colorType == PngColorType.GrayscaleWithAlpha)
{
var luminance = ImageMath.Get8BitBT709Luminance(expectedColor.R, expectedColor.G, expectedColor.B);
var luminance = ColorNumerics.Get8BitBT709Luminance(expectedColor.R, expectedColor.G, expectedColor.B);
expectedColor = new Rgba32(luminance, luminance, luminance);
}

6
tests/ImageSharp.Tests/Helpers/ImageMathTests.cs → tests/ImageSharp.Tests/Helpers/ColorNumericsTests.cs

@ -7,7 +7,7 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests.Helpers
{
public class ImageMathTests
public class ColorNumericsTests
{
[Theory]
[InlineData(0.2f, 0.7f, 0.1f, 256, 140)]
@ -20,12 +20,12 @@ namespace SixLabors.ImageSharp.Tests.Helpers
var vector = new Vector4(x, y, z, 0.0f);
// act
int actual = ImageMath.GetBT709Luminance(ref vector, luminanceLevels);
int actual = ColorNumerics.GetBT709Luminance(ref vector, luminanceLevels);
// assert
Assert.Equal(expected, actual);
}
// TODO: We need to test all ImageMaths methods!
// TODO: We need to test all ColorNumerics methods!
}
}

46
tests/ImageSharp.Tests/Helpers/NumericsTests.cs

@ -2,13 +2,17 @@
// Licensed under the Apache License, Version 2.0.
using System;
using System.Linq;
using System.Numerics;
using Xunit;
namespace SixLabors.ImageSharp.Tests.Helpers
{
public class NumericsTests
{
public delegate void SpanAction<T, in TArg, in TArg1>(Span<T> span, TArg arg, TArg1 arg1);
private delegate void SpanAction<T, in TArg, in TArg1>(Span<T> span, TArg arg, TArg1 arg1);
private readonly ApproximateFloatComparer approximateFloatComparer = new ApproximateFloatComparer(1e-6f);
[Theory]
[InlineData(0)]
@ -154,6 +158,46 @@ namespace SixLabors.ImageSharp.Tests.Helpers
Assert.Equal(expected, actual);
}
[Theory]
[InlineData(0)]
[InlineData(1)]
[InlineData(30)]
[InlineData(63)]
public void PremultiplyVectorSpan(int length)
{
var rnd = new Random(42);
Vector4[] source = rnd.GenerateRandomVectorArray(length, 0, 1);
Vector4[] expected = source.Select(v =>
{
Numerics.Premultiply(ref v);
return v;
}).ToArray();
Numerics.Premultiply(source);
Assert.Equal(expected, source, this.approximateFloatComparer);
}
[Theory]
[InlineData(0)]
[InlineData(1)]
[InlineData(30)]
[InlineData(63)]
public void UnPremultiplyVectorSpan(int length)
{
var rnd = new Random(42);
Vector4[] source = rnd.GenerateRandomVectorArray(length, 0, 1);
Vector4[] expected = source.Select(v =>
{
Numerics.UnPremultiply(ref v);
return v;
}).ToArray();
Numerics.UnPremultiply(source);
Assert.Equal(expected, source, this.approximateFloatComparer);
}
[Theory]
[InlineData(64, 36, 96)]
[InlineData(128, 16, 196)]

56
tests/ImageSharp.Tests/Helpers/Vector4UtilsTests.cs

@ -1,56 +0,0 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Linq;
using System.Numerics;
using Xunit;
namespace SixLabors.ImageSharp.Tests.Helpers
{
public class Vector4UtilsTests
{
private readonly ApproximateFloatComparer approximateFloatComparer = new ApproximateFloatComparer(1e-6f);
[Theory]
[InlineData(0)]
[InlineData(1)]
[InlineData(30)]
[InlineData(63)]
public void Premultiply_VectorSpan(int length)
{
var rnd = new Random(42);
Vector4[] source = rnd.GenerateRandomVectorArray(length, 0, 1);
Vector4[] expected = source.Select(v =>
{
Vector4Utils.Premultiply(ref v);
return v;
}).ToArray();
Vector4Utils.Premultiply(source);
Assert.Equal(expected, source, this.approximateFloatComparer);
}
[Theory]
[InlineData(0)]
[InlineData(1)]
[InlineData(30)]
[InlineData(63)]
public void UnPremultiply_VectorSpan(int length)
{
var rnd = new Random(42);
Vector4[] source = rnd.GenerateRandomVectorArray(length, 0, 1);
Vector4[] expected = source.Select(v =>
{
Vector4Utils.UnPremultiply(ref v);
return v;
}).ToArray();
Vector4Utils.UnPremultiply(source);
Assert.Equal(expected, source, this.approximateFloatComparer);
}
}
}

6
tests/ImageSharp.Tests/PixelFormats/L16Tests.cs

@ -113,8 +113,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
// Arrange
L16 gray = default;
const byte rgb = 128;
ushort scaledRgb = ImageMath.UpscaleFrom8BitTo16Bit(rgb);
ushort expected = ImageMath.Get16BitBT709Luminance(scaledRgb, scaledRgb, scaledRgb);
ushort scaledRgb = ColorNumerics.UpscaleFrom8BitTo16Bit(rgb);
ushort expected = ColorNumerics.Get16BitBT709Luminance(scaledRgb, scaledRgb, scaledRgb);
// Act
gray.FromRgba32(new Rgba32(rgb, rgb, rgb));
@ -131,7 +131,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
public void L16_ToRgba32(ushort input)
{
// Arrange
ushort expected = ImageMath.DownScaleFrom16BitTo8Bit(input);
ushort expected = ColorNumerics.DownScaleFrom16BitTo8Bit(input);
var gray = new L16(input);
// Act

2
tests/ImageSharp.Tests/PixelFormats/L8Tests.cs

@ -136,7 +136,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
{
// Arrange
L8 gray = default;
byte expected = ImageMath.Get8BitBT709Luminance(rgb, rgb, rgb);
byte expected = ColorNumerics.Get8BitBT709Luminance(rgb, rgb, rgb);
// Act
gray.FromRgba32(new Rgba32(rgb, rgb, rgb));

2
tests/ImageSharp.Tests/PixelFormats/La16Tests.cs

@ -138,7 +138,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
{
// Arrange
La16 gray = default;
byte expected = ImageMath.Get8BitBT709Luminance(rgb, rgb, rgb);
byte expected = ColorNumerics.Get8BitBT709Luminance(rgb, rgb, rgb);
// Act
gray.FromRgba32(new Rgba32(rgb, rgb, rgb));

6
tests/ImageSharp.Tests/PixelFormats/La32Tests.cs

@ -117,8 +117,8 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
// Arrange
La32 gray = default;
const byte rgb = 128;
ushort scaledRgb = ImageMath.UpscaleFrom8BitTo16Bit(rgb);
ushort expected = ImageMath.Get16BitBT709Luminance(scaledRgb, scaledRgb, scaledRgb);
ushort scaledRgb = ColorNumerics.UpscaleFrom8BitTo16Bit(rgb);
ushort expected = ColorNumerics.Get16BitBT709Luminance(scaledRgb, scaledRgb, scaledRgb);
// Act
gray.FromRgba32(new Rgba32(rgb, rgb, rgb));
@ -136,7 +136,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats
public void La32_ToRgba32(ushort input)
{
// Arrange
ushort expected = ImageMath.DownScaleFrom16BitTo8Bit(input);
ushort expected = ColorNumerics.DownScaleFrom16BitTo8Bit(input);
var gray = new La32(input, ushort.MaxValue);
// Act

24
tests/ImageSharp.Tests/PixelFormats/PixelOperations/PixelOperationsTests.cs

@ -197,7 +197,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
if (this.HasUnassociatedAlpha)
{
Vector4Utils.Premultiply(ref v);
Numerics.Premultiply(ref v);
}
}
@ -205,7 +205,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
if (this.HasUnassociatedAlpha)
{
Vector4Utils.UnPremultiply(ref v);
Numerics.UnPremultiply(ref v);
}
}
@ -232,7 +232,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
if (this.HasUnassociatedAlpha)
{
Vector4Utils.Premultiply(ref v);
Numerics.Premultiply(ref v);
}
}
@ -240,7 +240,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
if (this.HasUnassociatedAlpha)
{
Vector4Utils.UnPremultiply(ref v);
Numerics.UnPremultiply(ref v);
}
}
@ -273,7 +273,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
if (this.HasUnassociatedAlpha)
{
Vector4Utils.Premultiply(ref v);
Numerics.Premultiply(ref v);
}
}
@ -281,7 +281,7 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
if (this.HasUnassociatedAlpha)
{
Vector4Utils.UnPremultiply(ref v);
Numerics.UnPremultiply(ref v);
}
SRgbCompanding.Compress(ref v);
@ -394,12 +394,12 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
void SourceAction(ref Vector4 v)
{
Vector4Utils.UnPremultiply(ref v);
Numerics.UnPremultiply(ref v);
}
void ExpectedAction(ref Vector4 v)
{
Vector4Utils.Premultiply(ref v);
Numerics.Premultiply(ref v);
}
TPixel[] source = CreatePixelTestData(count, (ref Vector4 v) => SourceAction(ref v));
@ -417,12 +417,12 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
void SourceAction(ref Vector4 v)
{
Vector4Utils.UnPremultiply(ref v);
Numerics.UnPremultiply(ref v);
}
void ExpectedAction(ref Vector4 v)
{
Vector4Utils.Premultiply(ref v);
Numerics.Premultiply(ref v);
}
TPixel[] source = CreateScaledPixelTestData(count, (ref Vector4 v) => SourceAction(ref v));
@ -444,14 +444,14 @@ namespace SixLabors.ImageSharp.Tests.PixelFormats.PixelOperations
{
void SourceAction(ref Vector4 v)
{
Vector4Utils.UnPremultiply(ref v);
Numerics.UnPremultiply(ref v);
SRgbCompanding.Compress(ref v);
}
void ExpectedAction(ref Vector4 v)
{
SRgbCompanding.Expand(ref v);
Vector4Utils.Premultiply(ref v);
Numerics.Premultiply(ref v);
}
TPixel[] source = CreateScaledPixelTestData(count, (ref Vector4 v) => SourceAction(ref v));

Loading…
Cancel
Save