|
|
@ -281,31 +281,95 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components |
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
/// <param name="value">The value to multiply by.</param>
|
|
|
/// <param name="value">The value to multiply by.</param>
|
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
public void MultiplyInplace(float value) |
|
|
public void MultiplyInPlace(float value) |
|
|
{ |
|
|
{ |
|
|
this.V0L *= value; |
|
|
#if SUPPORTS_RUNTIME_INTRINSICS
|
|
|
this.V0R *= value; |
|
|
if (Avx.IsSupported) |
|
|
this.V1L *= value; |
|
|
{ |
|
|
this.V1R *= value; |
|
|
var valueVec = Vector256.Create(value); |
|
|
this.V2L *= value; |
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V0L) = Avx.Multiply(Unsafe.As<Vector4, Vector256<float>>(ref this.V0L), valueVec); |
|
|
this.V2R *= value; |
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V1L) = Avx.Multiply(Unsafe.As<Vector4, Vector256<float>>(ref this.V1L), valueVec); |
|
|
this.V3L *= value; |
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V2L) = Avx.Multiply(Unsafe.As<Vector4, Vector256<float>>(ref this.V2L), valueVec); |
|
|
this.V3R *= value; |
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V3L) = Avx.Multiply(Unsafe.As<Vector4, Vector256<float>>(ref this.V3L), valueVec); |
|
|
this.V4L *= value; |
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V4L) = Avx.Multiply(Unsafe.As<Vector4, Vector256<float>>(ref this.V4L), valueVec); |
|
|
this.V4R *= value; |
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V5L) = Avx.Multiply(Unsafe.As<Vector4, Vector256<float>>(ref this.V5L), valueVec); |
|
|
this.V5L *= value; |
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V6L) = Avx.Multiply(Unsafe.As<Vector4, Vector256<float>>(ref this.V6L), valueVec); |
|
|
this.V5R *= value; |
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V7L) = Avx.Multiply(Unsafe.As<Vector4, Vector256<float>>(ref this.V7L), valueVec); |
|
|
this.V6L *= value; |
|
|
} |
|
|
this.V6R *= value; |
|
|
else |
|
|
this.V7L *= value; |
|
|
#endif
|
|
|
this.V7R *= value; |
|
|
{ |
|
|
|
|
|
var valueVec = new Vector4(value); |
|
|
|
|
|
this.V0L *= valueVec; |
|
|
|
|
|
this.V0R *= valueVec; |
|
|
|
|
|
this.V1L *= valueVec; |
|
|
|
|
|
this.V1R *= valueVec; |
|
|
|
|
|
this.V2L *= valueVec; |
|
|
|
|
|
this.V2R *= valueVec; |
|
|
|
|
|
this.V3L *= valueVec; |
|
|
|
|
|
this.V3R *= valueVec; |
|
|
|
|
|
this.V4L *= valueVec; |
|
|
|
|
|
this.V4R *= valueVec; |
|
|
|
|
|
this.V5L *= valueVec; |
|
|
|
|
|
this.V5R *= valueVec; |
|
|
|
|
|
this.V6L *= valueVec; |
|
|
|
|
|
this.V6R *= valueVec; |
|
|
|
|
|
this.V7L *= valueVec; |
|
|
|
|
|
this.V7R *= valueVec; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// Multiply all elements of the block by the corresponding elements of 'other'.
|
|
|
/// Multiply all elements of the block by the corresponding elements of 'other'.
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
public void MultiplyInplace(ref Block8x8F other) |
|
|
public unsafe void MultiplyInPlace(ref Block8x8F other) |
|
|
|
|
|
{ |
|
|
|
|
|
#if SUPPORTS_RUNTIME_INTRINSICS
|
|
|
|
|
|
if (Avx.IsSupported) |
|
|
|
|
|
{ |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V0L) |
|
|
|
|
|
= Avx.Multiply( |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V0L), |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref other.V0L)); |
|
|
|
|
|
|
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V1L) |
|
|
|
|
|
= Avx.Multiply( |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V1L), |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref other.V1L)); |
|
|
|
|
|
|
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V2L) |
|
|
|
|
|
= Avx.Multiply( |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V2L), |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref other.V2L)); |
|
|
|
|
|
|
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V3L) |
|
|
|
|
|
= Avx.Multiply( |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V3L), |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref other.V3L)); |
|
|
|
|
|
|
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V4L) |
|
|
|
|
|
= Avx.Multiply( |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V4L), |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref other.V4L)); |
|
|
|
|
|
|
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V5L) |
|
|
|
|
|
= Avx.Multiply( |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V5L), |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref other.V5L)); |
|
|
|
|
|
|
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V6L) |
|
|
|
|
|
= Avx.Multiply( |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V6L), |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref other.V6L)); |
|
|
|
|
|
|
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V7L) |
|
|
|
|
|
= Avx.Multiply( |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V7L), |
|
|
|
|
|
Unsafe.As<Vector4, Vector256<float>>(ref other.V7L)); |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
#endif
|
|
|
{ |
|
|
{ |
|
|
this.V0L *= other.V0L; |
|
|
this.V0L *= other.V0L; |
|
|
this.V0R *= other.V0R; |
|
|
this.V0R *= other.V0R; |
|
|
@ -324,30 +388,49 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components |
|
|
this.V7L *= other.V7L; |
|
|
this.V7L *= other.V7L; |
|
|
this.V7R *= other.V7R; |
|
|
this.V7R *= other.V7R; |
|
|
} |
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// Adds a vector to all elements of the block.
|
|
|
/// Adds a vector to all elements of the block.
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
/// <param name="diff">The added vector</param>
|
|
|
/// <param name="value">The added vector.</param>
|
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
[MethodImpl(InliningOptions.ShortMethod)] |
|
|
public void AddToAllInplace(Vector4 diff) |
|
|
public void AddInPlace(float value) |
|
|
{ |
|
|
{ |
|
|
this.V0L += diff; |
|
|
#if SUPPORTS_RUNTIME_INTRINSICS
|
|
|
this.V0R += diff; |
|
|
if (Avx.IsSupported) |
|
|
this.V1L += diff; |
|
|
{ |
|
|
this.V1R += diff; |
|
|
var valueVec = Vector256.Create(value); |
|
|
this.V2L += diff; |
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V0L) = Avx.Add(Unsafe.As<Vector4, Vector256<float>>(ref this.V0L), valueVec); |
|
|
this.V2R += diff; |
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V1L) = Avx.Add(Unsafe.As<Vector4, Vector256<float>>(ref this.V1L), valueVec); |
|
|
this.V3L += diff; |
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V2L) = Avx.Add(Unsafe.As<Vector4, Vector256<float>>(ref this.V2L), valueVec); |
|
|
this.V3R += diff; |
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V3L) = Avx.Add(Unsafe.As<Vector4, Vector256<float>>(ref this.V3L), valueVec); |
|
|
this.V4L += diff; |
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V4L) = Avx.Add(Unsafe.As<Vector4, Vector256<float>>(ref this.V4L), valueVec); |
|
|
this.V4R += diff; |
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V5L) = Avx.Add(Unsafe.As<Vector4, Vector256<float>>(ref this.V5L), valueVec); |
|
|
this.V5L += diff; |
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V6L) = Avx.Add(Unsafe.As<Vector4, Vector256<float>>(ref this.V6L), valueVec); |
|
|
this.V5R += diff; |
|
|
Unsafe.As<Vector4, Vector256<float>>(ref this.V7L) = Avx.Add(Unsafe.As<Vector4, Vector256<float>>(ref this.V7L), valueVec); |
|
|
this.V6L += diff; |
|
|
} |
|
|
this.V6R += diff; |
|
|
else |
|
|
this.V7L += diff; |
|
|
#endif
|
|
|
this.V7R += diff; |
|
|
{ |
|
|
|
|
|
var valueVec = new Vector4(value); |
|
|
|
|
|
this.V0L += valueVec; |
|
|
|
|
|
this.V0R += valueVec; |
|
|
|
|
|
this.V1L += valueVec; |
|
|
|
|
|
this.V1R += valueVec; |
|
|
|
|
|
this.V2L += valueVec; |
|
|
|
|
|
this.V2R += valueVec; |
|
|
|
|
|
this.V3L += valueVec; |
|
|
|
|
|
this.V3R += valueVec; |
|
|
|
|
|
this.V4L += valueVec; |
|
|
|
|
|
this.V4R += valueVec; |
|
|
|
|
|
this.V5L += valueVec; |
|
|
|
|
|
this.V5R += valueVec; |
|
|
|
|
|
this.V6L += valueVec; |
|
|
|
|
|
this.V6R += valueVec; |
|
|
|
|
|
this.V7L += valueVec; |
|
|
|
|
|
this.V7R += valueVec; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
@ -468,23 +551,23 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components |
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// Level shift by +maximum/2, clip to [0..maximum], and round all the values in the block.
|
|
|
/// Level shift by +maximum/2, clip to [0..maximum], and round all the values in the block.
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
public void NormalizeColorsAndRoundInplace(float maximum) |
|
|
public void NormalizeColorsAndRoundInPlace(float maximum) |
|
|
{ |
|
|
{ |
|
|
if (SimdUtils.HasVector8) |
|
|
if (SimdUtils.HasVector8) |
|
|
{ |
|
|
{ |
|
|
this.NormalizeColorsAndRoundInplaceVector8(maximum); |
|
|
this.NormalizeColorsAndRoundInPlaceVector8(maximum); |
|
|
} |
|
|
} |
|
|
else |
|
|
else |
|
|
{ |
|
|
{ |
|
|
this.NormalizeColorsInplace(maximum); |
|
|
this.NormalizeColorsInPlace(maximum); |
|
|
this.RoundInplace(); |
|
|
this.RoundInPlace(); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
/// <summary>
|
|
|
/// Rounds all values in the block.
|
|
|
/// Rounds all values in the block.
|
|
|
/// </summary>
|
|
|
/// </summary>
|
|
|
public void RoundInplace() |
|
|
public void RoundInPlace() |
|
|
{ |
|
|
{ |
|
|
for (int i = 0; i < Size; i++) |
|
|
for (int i = 0; i < Size; i++) |
|
|
{ |
|
|
{ |
|
|
|