Browse Source

Vector color converters can work with any available vector size instead of 8

pull/1864/head
Dmitry Pentin 5 years ago
parent
commit
45e4768b91
  1. 6
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykVector.cs
  2. 6
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScaleVector.cs
  3. 6
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgbVector.cs
  4. 6
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrVector.cs
  5. 6
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccKVector.cs
  6. 10
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterBase.cs
  7. 30
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterVector.cs
  8. 2
      tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs
  9. 2
      tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs
  10. 2
      tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs
  11. 2
      tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs
  12. 8
      tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs

6
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykVector8.cs → src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykVector.cs

@ -9,9 +9,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
internal abstract partial class JpegColorConverterBase
{
internal sealed class FromCmykVector8 : VectorizedJpegColorConverter
internal sealed class FromCmykVector : VectorizedJpegColorConverter
{
public FromCmykVector8(int precision)
public FromCmykVector(int precision)
: base(JpegColorSpace.Cmyk, precision)
{
}
@ -29,7 +29,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
var scale = new Vector<float>(1 / this.MaximumValue);
nint n = values.Component0.Length / 8;
nint n = values.Component0.Length / Vector<float>.Count;
for (nint i = 0; i < n; i++)
{
ref Vector<float> c = ref Unsafe.Add(ref cBase, i);

6
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScaleVector8.cs → src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScaleVector.cs

@ -9,9 +9,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
internal abstract partial class JpegColorConverterBase
{
internal sealed class FromGrayScaleVector8 : VectorizedJpegColorConverter
internal sealed class FromGrayScaleVector : VectorizedJpegColorConverter
{
public FromGrayScaleVector8(int precision)
public FromGrayScaleVector(int precision)
: base(JpegColorSpace.Grayscale, precision)
{
}
@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
var scale = new Vector<float>(1 / this.MaximumValue);
nint n = values.Component0.Length / 8;
nint n = values.Component0.Length / Vector<float>.Count;
for (nint i = 0; i < n; i++)
{
ref Vector<float> c0 = ref Unsafe.Add(ref cBase, i);

6
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgbVector8.cs → src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgbVector.cs

@ -9,9 +9,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
internal abstract partial class JpegColorConverterBase
{
internal sealed class FromRgbVector8 : VectorizedJpegColorConverter
internal sealed class FromRgbVector : VectorizedJpegColorConverter
{
public FromRgbVector8(int precision)
public FromRgbVector(int precision)
: base(JpegColorSpace.RGB, precision)
{
}
@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
var scale = new Vector<float>(1 / this.MaximumValue);
nint n = values.Component0.Length / 8;
nint n = values.Component0.Length / Vector<float>.Count;
for (nint i = 0; i < n; i++)
{
ref Vector<float> r = ref Unsafe.Add(ref rBase, i);

6
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrVector8.cs → src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrVector.cs

@ -10,9 +10,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
internal abstract partial class JpegColorConverterBase
{
internal sealed class FromYCbCrVector8 : VectorizedJpegColorConverter
internal sealed class FromYCbCrVector : VectorizedJpegColorConverter
{
public FromYCbCrVector8(int precision)
public FromYCbCrVector(int precision)
: base(JpegColorSpace.YCbCr, precision)
{
}
@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
var gCrMult = new Vector<float>(-FromYCbCrScalar.GCrMult);
var bCbMult = new Vector<float>(FromYCbCrScalar.BCbMult);
nint n = values.Component0.Length / 8;
nint n = values.Component0.Length / Vector<float>.Count;
for (nint i = 0; i < n; i++)
{
// y = yVals[i];

6
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccKVector8.cs → src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccKVector.cs

@ -9,9 +9,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
internal abstract partial class JpegColorConverterBase
{
internal sealed class FromYccKVector8 : VectorizedJpegColorConverter
internal sealed class FromYccKVector : VectorizedJpegColorConverter
{
public FromYccKVector8(int precision)
public FromYccKVector(int precision)
: base(JpegColorSpace.Ycck, precision)
{
}
@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
var gCrMult = new Vector<float>(-FromYCbCrScalar.GCrMult);
var bCbMult = new Vector<float>(FromYCbCrScalar.BCbMult);
nint n = values.Component0.Length / 8;
nint n = values.Component0.Length / Vector<float>.Count;
for (nint i = 0; i < n; i++)
{
// y = yVals[i];

10
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterBase.cs

@ -111,7 +111,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
#if SUPPORTS_RUNTIME_INTRINSICS
yield return new FromYCbCrAvx(precision);
#endif
yield return new FromYCbCrVector8(precision);
yield return new FromYCbCrVector(precision);
yield return new FromYCbCrScalar(precision);
}
@ -123,7 +123,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
#if SUPPORTS_RUNTIME_INTRINSICS
yield return new FromYccKAvx(precision);
#endif
yield return new FromYccKVector8(precision);
yield return new FromYccKVector(precision);
yield return new FromYccKScalar(precision);
}
@ -135,7 +135,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
#if SUPPORTS_RUNTIME_INTRINSICS
yield return new FromCmykAvx(precision);
#endif
yield return new FromCmykVector8(precision);
yield return new FromCmykVector(precision);
yield return new FromCmykScalar(precision);
}
@ -147,7 +147,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
#if SUPPORTS_RUNTIME_INTRINSICS
yield return new FromGrayscaleAvx(precision);
#endif
yield return new FromGrayScaleVector8(precision);
yield return new FromGrayScaleVector(precision);
yield return new FromGrayscaleScalar(precision);
}
@ -159,7 +159,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
#if SUPPORTS_RUNTIME_INTRINSICS
yield return new FromRgbAvx(precision);
#endif
yield return new FromRgbVector8(precision);
yield return new FromRgbVector(precision);
yield return new FromRgbScalar(precision);
}

30
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverterVector.cs

@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0.
using System;
using System.Numerics;
namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
@ -9,7 +10,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
/// <summary>
/// <see cref="JpegColorConverterBase"/> abstract base for implementations
/// based on <see cref="System.Numerics.Vector"/> API.
/// based on <see cref="Vector"/> API.
/// </summary>
/// <remarks>
/// Converters of this family can work with data of any size.
@ -25,27 +26,26 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
public sealed override bool IsAvailable => SimdUtils.HasVector8;
public sealed override bool IsAvailable => Vector<float>.Count % 4 == 0;
public override void ConvertToRgbInplace(in ComponentValues values)
{
DebugGuard.IsTrue(this.IsAvailable, $"{this.GetType().Name} converter is not supported on current hardware");
int length = values.Component0.Length;
int remainder = values.Component0.Length % 8;
int remainder = values.Component0.Length % Vector<float>.Count;
// Jpeg images are guaranteed to have pixel strides at least 8 pixels wide
// Thus there's no need to check whether simdCount is greater than zero
int simdCount = length - remainder;
if (simdCount > 0)
this.ConvertCoreVectorizedInplace(values.Slice(0, simdCount));
// There's actually a lot of image/photo resolutions which won't have
// a remainder so it's better to check here than spend useless virtual call
if (remainder > 0)
{
// This implementation is actually AVX specific.
// An AVX register is capable of storing 8 float-s.
if (!this.IsAvailable)
{
throw new InvalidOperationException(
"This converter can be used only on architecture having 256 byte floating point SIMD registers!");
}
this.ConvertCoreVectorizedInplace(values.Slice(0, simdCount));
this.ConvertCoreInplace(values.Slice(simdCount, remainder));
}
this.ConvertCoreInplace(values.Slice(simdCount, remainder));
}
protected virtual void ConvertCoreVectorizedInplace(in ComponentValues values) => throw new NotImplementedException();

2
tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs

@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg
{
var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
new JpegColorConverterBase.FromCmykVector8(8).ConvertToRgbInplace(values);
new JpegColorConverterBase.FromCmykVector(8).ConvertToRgbInplace(values);
}
#if SUPPORTS_RUNTIME_INTRINSICS

2
tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs

@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg
{
var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
new JpegColorConverterBase.FromRgbVector8(8).ConvertToRgbInplace(values);
new JpegColorConverterBase.FromRgbVector(8).ConvertToRgbInplace(values);
}
#if SUPPORTS_RUNTIME_INTRINSICS

2
tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs

@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg
{
var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
new JpegColorConverterBase.FromYCbCrVector8(8).ConvertToRgbInplace(values);
new JpegColorConverterBase.FromYCbCrVector(8).ConvertToRgbInplace(values);
}
#if SUPPORTS_RUNTIME_INTRINSICS

2
tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs

@ -27,7 +27,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg
{
var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
new JpegColorConverterBase.FromYccKVector8(8).ConvertToRgbInplace(values);
new JpegColorConverterBase.FromYccKVector(8).ConvertToRgbInplace(values);
}
#if SUPPORTS_RUNTIME_INTRINSICS

8
tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs

@ -63,7 +63,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
}
ValidateConversion(
new JpegColorConverterBase.FromYCbCrVector8(8),
new JpegColorConverterBase.FromYCbCrVector(8),
3,
inputBufferLength,
resultBufferLength,
@ -128,7 +128,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
}
ValidateConversion(
new JpegColorConverterBase.FromCmykVector8(8),
new JpegColorConverterBase.FromCmykVector(8),
4,
inputBufferLength,
resultBufferLength,
@ -240,7 +240,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
}
ValidateConversion(
new JpegColorConverterBase.FromRgbVector8(8),
new JpegColorConverterBase.FromRgbVector(8),
3,
inputBufferLength,
resultBufferLength,
@ -305,7 +305,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
}
ValidateConversion(
new JpegColorConverterBase.FromYccKVector8(8),
new JpegColorConverterBase.FromYccKVector(8),
4,
inputBufferLength,
resultBufferLength,

Loading…
Cancel
Save