Skip to content

Commit

Permalink
Merge pull request #1886 from ynse01/add-Abgr32-pixel-type
Browse files Browse the repository at this point in the history
Add Abgr32 pixel type
  • Loading branch information
JimBobSquarePants authored Dec 18, 2021
2 parents ecd3db2 + a94b8c4 commit 5e060ba
Show file tree
Hide file tree
Showing 71 changed files with 2,129 additions and 151 deletions.
2 changes: 2 additions & 0 deletions src/ImageSharp/Advanced/AotCompilerTools.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ private static void SeedPixelFormats()

Seed<A8>();
Seed<Argb32>();
Seed<Abgr32>();
Seed<Bgr24>();
Seed<Bgr565>();
Seed<Bgra32>();
Expand Down Expand Up @@ -149,6 +150,7 @@ private static unsafe void AotCompileImage<TPixel>()
Image<TPixel> img = default;
img.CloneAs<A8>(default);
img.CloneAs<Argb32>(default);
img.CloneAs<Abgr32>(default);
img.CloneAs<Bgr24>(default);
img.CloneAs<Bgr565>(default);
img.CloneAs<Bgra32>(default);
Expand Down
24 changes: 24 additions & 0 deletions src/ImageSharp/Color/Color.Conversions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ public Color(Bgra32 pixel)
this.boxedHighPrecisionPixel = null;
}

/// <summary>
/// Initializes a new instance of the <see cref="Color"/> struct.
/// </summary>
/// <param name="pixel">The <see cref="Abgr32"/> containing the color information.</param>
[MethodImpl(InliningOptions.ShortMethod)]
public Color(Abgr32 pixel)
{
this.data = new Rgba64(pixel);
this.boxedHighPrecisionPixel = null;
}

/// <summary>
/// Initializes a new instance of the <see cref="Color"/> struct.
/// </summary>
Expand Down Expand Up @@ -177,6 +188,19 @@ internal Argb32 ToArgb32()
return value;
}

[MethodImpl(InliningOptions.ShortMethod)]
internal Abgr32 ToAbgr32()
{
if (this.boxedHighPrecisionPixel is null)
{
return this.data.ToAbgr32();
}

Abgr32 value = default;
value.FromScaledVector4(this.boxedHighPrecisionPixel.ToScaledVector4());
return value;
}

[MethodImpl(InliningOptions.ShortMethod)]
internal Rgb24 ToRgb24()
{
Expand Down
56 changes: 56 additions & 0 deletions src/ImageSharp/Common/Helpers/Numerics.cs
Original file line number Diff line number Diff line change
Expand Up @@ -907,5 +907,61 @@ ref MemoryMarshal.GetReference(Log2DeBruijn),
/// <param name="divisor">Divisor value.</param>
/// <returns>Ceiled division result.</returns>
public static uint DivideCeil(uint value, uint divisor) => (value + divisor - 1) / divisor;

/// <summary>
/// Rotates the specified value left by the specified number of bits.
/// </summary>
/// <param name="value">The value to rotate.</param>
/// <param name="offset">The number of bits to rotate with.</param>
/// <returns>The rotated value.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint RotateLeft(uint value, int offset)
{
#if SUPPORTS_BITOPERATIONS
return BitOperations.RotateLeft(value, offset);
#else
return RotateLeftSoftwareFallback(value, offset);
#endif
}

#if !SUPPORTS_BITOPERATIONS
/// <summary>
/// Rotates the specified value left by the specified number of bits.
/// </summary>
/// <param name="value">The value to rotate.</param>
/// <param name="offset">The number of bits to rotate with.</param>
/// <returns>The rotated value.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint RotateLeftSoftwareFallback(uint value, int offset)
=> (value << offset) | (value >> (32 - offset));
#endif

/// <summary>
/// Rotates the specified value right by the specified number of bits.
/// </summary>
/// <param name="value">The value to rotate.</param>
/// <param name="offset">The number of bits to rotate with.</param>
/// <returns>The rotated value.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint RotateRight(uint value, int offset)
{
#if SUPPORTS_BITOPERATIONS
return BitOperations.RotateRight(value, offset);
#else
return RotateRightSoftwareFallback(value, offset);
#endif
}

#if !SUPPORTS_BITOPERATIONS
/// <summary>
/// Rotates the specified value right by the specified number of bits.
/// </summary>
/// <param name="value">The value to rotate.</param>
/// <param name="offset">The number of bits to rotate with.</param>
/// <returns>The rotated value.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint RotateRightSoftwareFallback(uint value, int offset)
=> (value >> offset) | (value << (32 - offset));
#endif
}
}
37 changes: 35 additions & 2 deletions src/ImageSharp/Common/Helpers/Shuffle/IComponentShuffle.cs
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)

// packed = [W Z Y X]
// ROTR(8, packedArgb) = [Y Z W X]
Unsafe.Add(ref dBase, i) = (packed >> 8) | (packed << 24);
Unsafe.Add(ref dBase, i) = Numerics.RotateRight(packed, 8);
}
}
}
Expand Down Expand Up @@ -188,7 +188,40 @@ public void RunFallbackShuffle(ReadOnlySpan<byte> source, Span<byte> dest)
// tmp1 + tmp3 = [W X Y Z]
uint tmp1 = packed & 0xFF00FF00;
uint tmp2 = packed & 0x00FF00FF;
uint tmp3 = (tmp2 << 16) | (tmp2 >> 16);
uint tmp3 = Numerics.RotateLeft(tmp2, 16);

Unsafe.Add(ref dBase, i) = tmp1 + tmp3;
}
}
}

internal readonly struct XWZYShuffle4 : IShuffle4
{
public byte Control
{
[MethodImpl(InliningOptions.ShortMethod)]
get => SimdUtils.Shuffle.MmShuffle(1, 2, 3, 0);
}

[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 uint dBase = ref Unsafe.As<byte, uint>(ref MemoryMarshal.GetReference(dest));
int n = source.Length / 4;

for (int i = 0; i < n; i++)
{
uint packed = Unsafe.Add(ref sBase, i);

// packed = [W Z Y X]
// tmp1 = [0 Z 0 X]
// tmp2 = [W 0 Y 0]
// tmp3=ROTL(16, tmp2) = [Y 0 W 0]
// tmp1 + tmp3 = [Y Z W X]
uint tmp1 = packed & 0x00FF00FF;
uint tmp2 = packed & 0xFF00FF00;
uint tmp3 = Numerics.RotateLeft(tmp2, 16);

Unsafe.Add(ref dBase, i) = tmp1 + tmp3;
}
Expand Down
9 changes: 9 additions & 0 deletions src/ImageSharp/ImageSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@
<AutoGen>True</AutoGen>
<DependentUpon>Block8x8F.Generated.tt</DependentUpon>
</Compile>
<Compile Update="PixelFormats\PixelImplementations\PixelOperations\Generated\Abgr32.PixelOperations.Generated.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Abgr32.PixelOperations.Generated.tt</DependentUpon>
</Compile>
<Compile Update="PixelFormats\PixelOperations{TPixel}.Generated.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
Expand Down Expand Up @@ -166,6 +171,10 @@
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>Block8x8F.Generated.cs</LastGenOutput>
</None>
<None Update="PixelFormats\PixelImplementations\PixelOperations\Generated\Abgr32.PixelOperations.Generated.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>Abgr32.PixelOperations.Generated.cs</LastGenOutput>
</None>
<None Update="PixelFormats\PixelOperations{TPixel}.Generated.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>PixelOperations{TPixel}.Generated.cs</LastGenOutput>
Expand Down
6 changes: 6 additions & 0 deletions src/ImageSharp/PixelFormats/IPixel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ public interface IPixel
/// <param name="source">The <see cref="Bgra32"/> value.</param>
void FromBgra32(Bgra32 source);

/// <summary>
/// Initializes the pixel instance from an <see cref="Abgr32"/> value.
/// </summary>
/// <param name="source">The <see cref="Abgr32"/> value.</param>
void FromAbgr32(Abgr32 source);

/// <summary>
/// Initializes the pixel instance from an <see cref="L8"/> value.
/// </summary>
Expand Down
4 changes: 4 additions & 0 deletions src/ImageSharp/PixelFormats/PixelImplementations/A8.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ public partial struct A8 : IPixel<A8>, IPackedVector<byte>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra32(Bgra32 source) => this.PackedValue = source.A;

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromAbgr32(Abgr32 source) => this.PackedValue = source.A;

/// <inheritdoc/>
[MethodImpl(InliningOptions.ShortMethod)]
public void FromBgra5551(Bgra5551 source) => this.FromScaledVector4(source.ToScaledVector4());
Expand Down
Loading

0 comments on commit 5e060ba

Please sign in to comment.