mirror of https://github.com/SixLabors/ImageSharp
8 changed files with 541 additions and 161 deletions
@ -0,0 +1,96 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Runtime.CompilerServices; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
namespace SixLabors.ImageSharp |
|||
{ |
|||
/// <inheritdoc/>
|
|||
internal interface IPad3Shuffle4 : IComponentShuffle |
|||
{ |
|||
} |
|||
|
|||
internal readonly struct DefaultPad3Shuffle4 : IPad3Shuffle4 |
|||
{ |
|||
private readonly byte p3; |
|||
private readonly byte p2; |
|||
private readonly byte p1; |
|||
private readonly byte p0; |
|||
|
|||
public DefaultPad3Shuffle4(byte p3, byte p2, byte p1, byte p0) |
|||
{ |
|||
this.p3 = p3; |
|||
this.p2 = p2; |
|||
this.p1 = p1; |
|||
this.p0 = p0; |
|||
this.Control = SimdUtils.Shuffle.MmShuffle(p3, p2, p1, p0); |
|||
} |
|||
|
|||
public byte Control { get; } |
|||
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest) |
|||
{ |
|||
ref byte sBase = ref MemoryMarshal.GetReference(source); |
|||
ref byte dBase = ref MemoryMarshal.GetReference(dest); |
|||
|
|||
int p3 = this.p3; |
|||
int p2 = this.p2; |
|||
int p1 = this.p1; |
|||
int p0 = this.p0; |
|||
|
|||
Span<byte> temp = stackalloc byte[4]; |
|||
ref byte t = ref MemoryMarshal.GetReference(temp); |
|||
ref uint tu = ref Unsafe.As<byte, uint>(ref t); |
|||
|
|||
for (int i = 0, j = 0; i < source.Length; i += 3, j += 4) |
|||
{ |
|||
ref var s = ref Unsafe.Add(ref sBase, i); |
|||
tu = Unsafe.As<byte, uint>(ref s) | 0xFF000000; |
|||
|
|||
Unsafe.Add(ref dBase, j) = Unsafe.Add(ref t, p0); |
|||
Unsafe.Add(ref dBase, j + 1) = Unsafe.Add(ref t, p1); |
|||
Unsafe.Add(ref dBase, j + 2) = Unsafe.Add(ref t, p2); |
|||
Unsafe.Add(ref dBase, j + 3) = Unsafe.Add(ref t, p3); |
|||
} |
|||
} |
|||
} |
|||
|
|||
internal readonly struct XYZWPad3Shuffle4 : IPad3Shuffle4 |
|||
{ |
|||
private static readonly byte XYZW = SimdUtils.Shuffle.MmShuffle(3, 2, 1, 0); |
|||
|
|||
public byte Control => XYZW; |
|||
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest) |
|||
{ |
|||
ref byte rs = ref MemoryMarshal.GetReference(source); |
|||
ref byte rd = ref MemoryMarshal.GetReference(dest); |
|||
|
|||
ref byte rsEnd = ref Unsafe.Add(ref rs, source.Length); |
|||
ref byte rsLoopEnd = ref Unsafe.Subtract(ref rsEnd, 4); |
|||
|
|||
while (Unsafe.IsAddressLessThan(ref rs, ref rsLoopEnd)) |
|||
{ |
|||
Unsafe.As<byte, uint>(ref rd) = Unsafe.As<byte, uint>(ref rs) | 0xFF000000; |
|||
|
|||
rs = ref Unsafe.Add(ref rs, 3); |
|||
rd = ref Unsafe.Add(ref rd, 4); |
|||
} |
|||
|
|||
while (Unsafe.IsAddressLessThan(ref rs, ref rsEnd)) |
|||
{ |
|||
Unsafe.Add(ref rd, 0) = Unsafe.Add(ref rs, 0); |
|||
Unsafe.Add(ref rd, 1) = Unsafe.Add(ref rs, 1); |
|||
Unsafe.Add(ref rd, 2) = Unsafe.Add(ref rs, 2); |
|||
Unsafe.Add(ref rd, 3) = byte.MaxValue; |
|||
|
|||
rs = ref Unsafe.Add(ref rs, 3); |
|||
rd = ref Unsafe.Add(ref rd, 4); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,74 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Runtime.CompilerServices; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
namespace SixLabors.ImageSharp |
|||
{ |
|||
/// <inheritdoc/>
|
|||
internal interface IShuffle4Slice3 : IComponentShuffle |
|||
{ |
|||
} |
|||
|
|||
internal readonly struct DefaultShuffle4Slice3 : IShuffle4Slice3 |
|||
{ |
|||
private readonly byte p2; |
|||
private readonly byte p1; |
|||
private readonly byte p0; |
|||
|
|||
public DefaultShuffle4Slice3(byte p3, byte p2, byte p1, byte p0) |
|||
{ |
|||
this.p2 = p2; |
|||
this.p1 = p1; |
|||
this.p0 = p0; |
|||
this.Control = SimdUtils.Shuffle.MmShuffle(p3, p2, p1, p0); |
|||
} |
|||
|
|||
public byte Control { get; } |
|||
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest) |
|||
{ |
|||
ref byte sBase = ref MemoryMarshal.GetReference(source); |
|||
ref byte dBase = ref MemoryMarshal.GetReference(dest); |
|||
|
|||
int p2 = this.p2; |
|||
int p1 = this.p1; |
|||
int p0 = this.p0; |
|||
|
|||
for (int i = 0, j = 0; i < dest.Length; i += 3, j += 4) |
|||
{ |
|||
Unsafe.Add(ref dBase, i) = Unsafe.Add(ref sBase, p0 + j); |
|||
Unsafe.Add(ref dBase, i + 1) = Unsafe.Add(ref sBase, p1 + j); |
|||
Unsafe.Add(ref dBase, i + 2) = Unsafe.Add(ref sBase, p2 + j); |
|||
} |
|||
} |
|||
} |
|||
|
|||
internal readonly struct XYZWShuffle4Slice3 : IShuffle4Slice3 |
|||
{ |
|||
private static readonly byte XYZW = SimdUtils.Shuffle.MmShuffle(3, 2, 1, 0); |
|||
|
|||
public byte Control => XYZW; |
|||
|
|||
[MethodImpl(InliningOptions.ShortMethod)] |
|||
public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest) |
|||
{ |
|||
ref uint sBase = ref Unsafe.As<byte, uint>(ref MemoryMarshal.GetReference(source)); |
|||
ref byte dBase = ref MemoryMarshal.GetReference(dest); |
|||
|
|||
int n = source.Length / 4; |
|||
for (int i = 0, j = 0; i < n; i++, j += 3) |
|||
{ |
|||
Unsafe.As<byte, Xyz24>(ref Unsafe.Add(ref dBase, j)) = Unsafe.As<uint, Xyz24>(ref Unsafe.Add(ref sBase, i)); |
|||
} |
|||
} |
|||
} |
|||
|
|||
[StructLayout(LayoutKind.Explicit, Size = 3)] |
|||
internal readonly struct Xyz24 |
|||
{ |
|||
} |
|||
} |
|||
Loading…
Reference in new issue