Browse Source

Respond to Anton fedback

js/color-alpha-handling
James Jackson-South 6 years ago
parent
commit
e3e8656d8f
  1. 7
      src/ImageSharp/Common/Helpers/SimdUtils.cs
  2. 6
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.Avx2JpegColorConverter.cs
  3. 2
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykAvx2.cs
  4. 8
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrVector4.cs
  5. 18
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs
  6. 2
      tests/ImageSharp.Benchmarks/Codecs/Jpeg/YCbCrColorConversion.cs
  7. 12
      tests/ImageSharp.Tests/Formats/Jpg/JpegColorConverterTests.cs

7
src/ImageSharp/Common/Helpers/SimdUtils.cs

@ -25,6 +25,13 @@ namespace SixLabors.ImageSharp
public static bool HasVector8 { get; } = public static bool HasVector8 { get; } =
Vector.IsHardwareAccelerated && Vector<float>.Count == 8 && Vector<int>.Count == 8; Vector.IsHardwareAccelerated && Vector<float>.Count == 8 && Vector<int>.Count == 8;
/// <summary>
/// Gets a value indicating whether <see cref="Vector{T}"/> code is being JIT-ed to SSE instructions
/// where float and integer registers are of size 128 byte.
/// </summary>
public static bool HasVector4 { get; } =
Vector.IsHardwareAccelerated && Vector<float>.Count == 4;
public static bool HasAvx2 public static bool HasAvx2
{ {
get get

6
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.Avx2JpegColorConverter.cs

@ -1,10 +1,6 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
#if SUPPORTS_RUNTIME_INTRINSICS
using System.Runtime.Intrinsics.X86;
#endif
namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{ {
internal abstract partial class JpegColorConverter internal abstract partial class JpegColorConverter

2
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykAvx2.cs

@ -1,4 +1,4 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System; using System;

8
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrVector.cs → src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrVector4.cs

@ -11,14 +11,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{ {
internal abstract partial class JpegColorConverter internal abstract partial class JpegColorConverter
{ {
internal sealed class FromYCbCrVector : VectorizedJpegColorConverter internal sealed class FromYCbCrVector4 : VectorizedJpegColorConverter
{ {
public FromYCbCrVector(int precision) public FromYCbCrVector4(int precision)
: base(JpegColorSpace.YCbCr, precision, 8) : base(JpegColorSpace.YCbCr, precision, 8)
{ {
} }
protected override bool IsAvailable => true; protected override bool IsAvailable => SimdUtils.HasVector4;
protected override void ConvertCoreVectorized(in ComponentValues values, Span<Vector4> result) protected override void ConvertCoreVectorized(in ComponentValues values, Span<Vector4> result)
{ {
@ -74,7 +74,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
tmp.MultiplyInplace(1.772F); tmp.MultiplyInplace(1.772F);
b.AddInplace(ref tmp); b.AddInplace(ref tmp);
if (Vector<float>.Count == 4) if (SimdUtils.HasVector4)
{ {
// TODO: Find a way to properly run & test this path on AVX2 PC-s! (Have I already mentioned that Vector<T> is terrible?) // TODO: Find a way to properly run & test this path on AVX2 PC-s! (Have I already mentioned that Vector<T> is terrible?)
r.RoundAndDownscalePreVector8(maxValue); r.RoundAndDownscalePreVector8(maxValue);

18
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs

@ -62,8 +62,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
/// </summary> /// </summary>
public static JpegColorConverter GetConverter(JpegColorSpace colorSpace, int precision) public static JpegColorConverter GetConverter(JpegColorSpace colorSpace, int precision)
{ {
JpegColorConverter converter = Array.Find(Converters, c => c.ColorSpace == colorSpace JpegColorConverter converter = Array.Find(
&& c.Precision == precision); Converters,
c => c.ColorSpace == colorSpace
&& c.Precision == precision);
if (converter is null) if (converter is null)
{ {
@ -94,7 +96,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
converters.AddRange(GetGrayScaleConverters(8)); converters.AddRange(GetGrayScaleConverters(8));
converters.AddRange(GetRgbConverters(8)); converters.AddRange(GetRgbConverters(8));
// 8-bit converters // 12-bit converters
converters.AddRange(GetYCbCrConverters(12)); converters.AddRange(GetYCbCrConverters(12));
converters.AddRange(GetYccKConverters(12)); converters.AddRange(GetYccKConverters(12));
converters.AddRange(GetCmykConverters(12)); converters.AddRange(GetCmykConverters(12));
@ -109,9 +111,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
/// </summary> /// </summary>
private static IEnumerable<JpegColorConverter> GetYCbCrConverters(int precision) private static IEnumerable<JpegColorConverter> GetYCbCrConverters(int precision)
{ {
#if SUPPORTS_RUNTIME_INTRINSICS
yield return new FromYCbCrAvx2(precision); yield return new FromYCbCrAvx2(precision);
#endif
yield return new FromYCbCrVector8(precision); yield return new FromYCbCrVector8(precision);
yield return new FromYCbCrVector(precision); yield return new FromYCbCrVector4(precision);
yield return new FromYCbCrBasic(precision); yield return new FromYCbCrBasic(precision);
} }
@ -120,7 +124,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
/// </summary> /// </summary>
private static IEnumerable<JpegColorConverter> GetYccKConverters(int precision) private static IEnumerable<JpegColorConverter> GetYccKConverters(int precision)
{ {
#if SUPPORTS_RUNTIME_INTRINSICS
yield return new FromYccKAvx2(precision); yield return new FromYccKAvx2(precision);
#endif
yield return new FromYccKVector8(precision); yield return new FromYccKVector8(precision);
yield return new FromYccKBasic(precision); yield return new FromYccKBasic(precision);
} }
@ -130,7 +136,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
/// </summary> /// </summary>
private static IEnumerable<JpegColorConverter> GetCmykConverters(int precision) private static IEnumerable<JpegColorConverter> GetCmykConverters(int precision)
{ {
#if SUPPORTS_RUNTIME_INTRINSICS
yield return new FromCmykAvx2(precision); yield return new FromCmykAvx2(precision);
#endif
yield return new FromCmykVector8(precision); yield return new FromCmykVector8(precision);
yield return new FromCmykBasic(precision); yield return new FromCmykBasic(precision);
} }
@ -140,7 +148,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
/// </summary> /// </summary>
private static IEnumerable<JpegColorConverter> GetGrayScaleConverters(int precision) private static IEnumerable<JpegColorConverter> GetGrayScaleConverters(int precision)
{ {
#if SUPPORTS_RUNTIME_INTRINSICS
yield return new FromGrayscaleAvx2(precision); yield return new FromGrayscaleAvx2(precision);
#endif
yield return new FromGrayscaleBasic(precision); yield return new FromGrayscaleBasic(precision);
} }

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

@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg
{ {
var values = new JpegColorConverter.ComponentValues(this.input, 0); var values = new JpegColorConverter.ComponentValues(this.input, 0);
new JpegColorConverter.FromYCbCrVector(8).ConvertToRgba(values, this.output); new JpegColorConverter.FromYCbCrVector4(8).ConvertToRgba(values, this.output);
} }
[Benchmark] [Benchmark]

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

@ -54,10 +54,16 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
[Theory] [Theory]
[MemberData(nameof(CommonConversionData))] [MemberData(nameof(CommonConversionData))]
public void FromYCbCrVector(int inputBufferLength, int resultBufferLength, int seed) public void FromYCbCrVector4(int inputBufferLength, int resultBufferLength, int seed)
{ {
if (!SimdUtils.HasVector4)
{
this.Output.WriteLine("No SSE present, skipping test!");
return;
}
ValidateConversion( ValidateConversion(
new JpegColorConverter.FromYCbCrVector(8), new JpegColorConverter.FromYCbCrVector4(8),
3, 3,
inputBufferLength, inputBufferLength,
resultBufferLength, resultBufferLength,
@ -346,7 +352,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
JpegColorConverter.ComponentValues values = CreateRandomValues(3, count, 1); JpegColorConverter.ComponentValues values = CreateRandomValues(3, count, 1);
var result = new Vector4[count]; var result = new Vector4[count];
JpegColorConverter converter = simd ? (JpegColorConverter)new JpegColorConverter.FromYCbCrVector(8) : new JpegColorConverter.FromYCbCrBasic(8); JpegColorConverter converter = simd ? (JpegColorConverter)new JpegColorConverter.FromYCbCrVector4(8) : new JpegColorConverter.FromYCbCrBasic(8);
// Warm up: // Warm up:
converter.ConvertToRgba(values, result); converter.ConvertToRgba(values, result);

Loading…
Cancel
Save