Browse Source

Try fix issues with Rgb96 pixel conversions

pull/3096/head
Brian Popow 1 month ago
parent
commit
787ebb205d
  1. 24
      src/ImageSharp/Common/Helpers/ColorNumerics.cs
  2. 44
      src/ImageSharp/PixelFormats/PixelImplementations/Rgb96.cs
  3. 3
      src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs

24
src/ImageSharp/Common/Helpers/ColorNumerics.cs

@ -12,8 +12,6 @@ namespace SixLabors.ImageSharp;
/// </summary>
internal static class ColorNumerics
{
private const float Scale32Bit = 1f / 0xFFFFFFFF;
/// <summary>
/// Vector for converting pixel to gray value as specified by
/// ITU-R Recommendation BT.709.
@ -141,7 +139,7 @@ internal static class ColorNumerics
/// <param name="component">The 32 bit component value.</param>
/// <returns>The <see cref="byte"/> value.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static byte From32BitTo8Bit(uint component) => (byte)(component * Scale32Bit);
public static byte From32BitTo8Bit(uint component) => (byte)(component >> 24);
/// <summary>
/// Scales a value from an 8 bit <see cref="byte"/> to
@ -153,6 +151,26 @@ internal static class ColorNumerics
public static ushort From8BitTo16Bit(byte component)
=> (ushort)(component * 257);
/// <summary>
/// Scales a value from an 16 bit <see cref="byte"/> to
/// an 16 bit <see cref="uint"/> equivalent.
/// </summary>
/// <param name="component">The 16 bit component value.</param>
/// <returns>The 32 bit <see cref="uint"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint From16BitTo32Bit(ushort component)
=> (uint)(component * 65537);
/// <summary>
/// Scales a value from an 8 bit <see cref="byte"/> to
/// an 32 bit <see cref="ushort"/> equivalent.
/// </summary>
/// <param name="component">The 8 bit component value.</param>
/// <returns>The 32 bit <see cref="uint"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static uint From8BitTo32Bit(byte component)
=> (uint)(component * 16843009);
/// <summary>
/// Returns how many bits are required to store the specified number of colors.
/// Performs a Log2() on the value.

44
src/ImageSharp/PixelFormats/PixelImplementations/Rgb96.cs

@ -19,7 +19,7 @@ public partial struct Rgb96 : IPixel<Rgb96>, IEquatable<Rgb96>
{
private const float InvMax = 1.0f / uint.MaxValue;
private const double Max = uint.MaxValue;
private const float Max = uint.MaxValue;
/// <summary>
/// Gets the red component.
@ -94,15 +94,19 @@ public partial struct Rgb96 : IPixel<Rgb96>, IEquatable<Rgb96>
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb96 FromVector4(Vector4 source) => FromVector4(source);
public static Rgb96 FromVector4(Vector4 source)
{
source = Numerics.Clamp(source, Vector4.Zero, Vector4.One) * Max;
return new Rgb96((uint)MathF.Round(source.X), (uint)MathF.Round(source.Y), (uint)MathF.Round(source.Z));
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb96 FromAbgr32(Abgr32 source) => new(source.R, source.G, source.B);
public static Rgb96 FromAbgr32(Abgr32 source) => new(ColorNumerics.From8BitTo32Bit(source.R), ColorNumerics.From8BitTo32Bit(source.G), ColorNumerics.From8BitTo32Bit(source.B));
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb96 FromArgb32(Argb32 source) => new(source.R, source.G, source.B);
public static Rgb96 FromArgb32(Argb32 source) => new(ColorNumerics.From8BitTo32Bit(source.R), ColorNumerics.From8BitTo32Bit(source.G), ColorNumerics.From8BitTo32Bit(source.B));
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -110,47 +114,59 @@ public partial struct Rgb96 : IPixel<Rgb96>, IEquatable<Rgb96>
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb96 FromBgr24(Bgr24 source) => new(source.R, source.G, source.B);
public static Rgb96 FromBgr24(Bgr24 source) => new(ColorNumerics.From8BitTo32Bit(source.R), ColorNumerics.From8BitTo32Bit(source.G), ColorNumerics.From8BitTo32Bit(source.B));
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb96 FromBgra32(Bgra32 source) => new(source.R, source.G, source.B);
public static Rgb96 FromBgra32(Bgra32 source) => new(ColorNumerics.From8BitTo32Bit(source.R), ColorNumerics.From8BitTo32Bit(source.G), ColorNumerics.From8BitTo32Bit(source.B));
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb96 FromL8(L8 source)
{
ushort rgb = ColorNumerics.From8BitTo16Bit(source.PackedValue);
uint rgb = ColorNumerics.From8BitTo32Bit(source.PackedValue);
return new Rgb96(rgb, rgb, rgb);
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb96 FromL16(L16 source) => new(source.PackedValue, source.PackedValue, source.PackedValue);
public static Rgb96 FromL16(L16 source)
{
uint rgb = ColorNumerics.From16BitTo32Bit(source.PackedValue);
return new(rgb, rgb, rgb);
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb96 FromLa16(La16 source) => new(source.PackedValue, source.PackedValue, source.PackedValue);
public static Rgb96 FromLa16(La16 source)
{
uint rgb = ColorNumerics.From8BitTo32Bit((byte)source.PackedValue);
return new(rgb, rgb, rgb);
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb96 FromLa32(La32 source) => new(source.L, source.L, source.L);
public static Rgb96 FromLa32(La32 source)
{
uint rgb = ColorNumerics.From16BitTo32Bit(source.L);
return new(rgb, rgb, rgb);
}
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb96 FromRgb24(Rgb24 source) => new(source.R, source.G, source.B);
public static Rgb96 FromRgb24(Rgb24 source) => new(ColorNumerics.From8BitTo32Bit(source.R), ColorNumerics.From8BitTo32Bit(source.G), ColorNumerics.From8BitTo32Bit(source.B));
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb96 FromRgba32(Rgba32 source) => new(source.R, source.G, source.B);
public static Rgb96 FromRgba32(Rgba32 source) => new(ColorNumerics.From8BitTo32Bit(source.R), ColorNumerics.From8BitTo32Bit(source.G), ColorNumerics.From8BitTo32Bit(source.B));
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb96 FromRgb48(Rgb48 source) => new(source.R, source.G, source.B);
public static Rgb96 FromRgb48(Rgb48 source) => new(ColorNumerics.From16BitTo32Bit(source.R), ColorNumerics.From16BitTo32Bit(source.G), ColorNumerics.From16BitTo32Bit(source.B));
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Rgb96 FromRgba64(Rgba64 source) => new(source.R, source.G, source.B);
public static Rgb96 FromRgba64(Rgba64 source) => new(ColorNumerics.From16BitTo32Bit(source.R), ColorNumerics.From16BitTo32Bit(source.G), ColorNumerics.From16BitTo32Bit(source.B));
/// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]

3
src/ImageSharp/PixelFormats/PixelImplementations/Rgba32.cs

@ -325,7 +325,8 @@ public partial struct Rgba32 : IPixel<Rgba32>, IPackedVector<uint>
{
R = ColorNumerics.From32BitTo8Bit(source.R),
G = ColorNumerics.From32BitTo8Bit(source.G),
B = ColorNumerics.From32BitTo8Bit(source.B)
B = ColorNumerics.From32BitTo8Bit(source.B),
A = byte.MaxValue
};
/// <summary>

Loading…
Cancel
Save