mirror of https://github.com/SixLabors/ImageSharp
39 changed files with 400 additions and 33 deletions
@ -0,0 +1,94 @@ |
|||
namespace ImageSharp.PixelFormats |
|||
{ |
|||
using System; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
[StructLayout(LayoutKind.Sequential)] |
|||
public struct Bgr24 : IPixel<Bgr24> |
|||
{ |
|||
/// <summary>
|
|||
/// Gets or sets the blue component.
|
|||
/// </summary>
|
|||
public byte B; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the green component.
|
|||
/// </summary>
|
|||
public byte G; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the red component.
|
|||
/// </summary>
|
|||
public byte R; |
|||
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public Bgr24(byte r, byte g, byte b) |
|||
{ |
|||
this.R = r; |
|||
this.G = g; |
|||
this.B = b; |
|||
} |
|||
|
|||
public PixelOperations<Bgr24> CreatePixelOperations() => new PixelOperations<Bgr24>(); |
|||
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool Equals(Bgr24 other) |
|||
{ |
|||
return this.R == other.R && this.G == other.G && this.B == other.B; |
|||
} |
|||
|
|||
public override bool Equals(object obj) |
|||
{ |
|||
return obj.GetType() == typeof(Bgr24) && this.Equals((Bgr24)obj); |
|||
} |
|||
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public override int GetHashCode() |
|||
{ |
|||
unchecked |
|||
{ |
|||
int hashCode = this.B; |
|||
hashCode = (hashCode * 397) ^ this.G; |
|||
hashCode = (hashCode * 397) ^ this.R; |
|||
return hashCode; |
|||
} |
|||
} |
|||
|
|||
public void PackFromBytes(byte x, byte y, byte z, byte w) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public void PackFromVector4(Vector4 vector) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public Vector4 ToVector4() |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public void ToXyzBytes(Span<byte> bytes, int startIndex) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public void ToXyzwBytes(Span<byte> bytes, int startIndex) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public void ToZyxBytes(Span<byte> bytes, int startIndex) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public void ToZyxwBytes(Span<byte> bytes, int startIndex) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,94 @@ |
|||
namespace ImageSharp.PixelFormats |
|||
{ |
|||
using System; |
|||
using System.Numerics; |
|||
using System.Runtime.CompilerServices; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
[StructLayout(LayoutKind.Sequential)] |
|||
public struct Rgb24 : IPixel<Rgb24> |
|||
{ |
|||
/// <summary>
|
|||
/// Gets or sets the red component.
|
|||
/// </summary>
|
|||
public byte R; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the green component.
|
|||
/// </summary>
|
|||
public byte G; |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the blue component.
|
|||
/// </summary>
|
|||
public byte B; |
|||
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public Rgb24(byte r, byte g, byte b) |
|||
{ |
|||
this.R = r; |
|||
this.G = g; |
|||
this.B = b; |
|||
} |
|||
|
|||
public PixelOperations<Rgb24> CreatePixelOperations() => new PixelOperations<Rgb24>(); |
|||
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public bool Equals(Rgb24 other) |
|||
{ |
|||
return this.R == other.R && this.G == other.G && this.B == other.B; |
|||
} |
|||
|
|||
public override bool Equals(object obj) |
|||
{ |
|||
return obj.GetType() == typeof(Rgb24) && this.Equals((Rgb24)obj); |
|||
} |
|||
|
|||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|||
public override int GetHashCode() |
|||
{ |
|||
unchecked |
|||
{ |
|||
int hashCode = this.R; |
|||
hashCode = (hashCode * 397) ^ this.G; |
|||
hashCode = (hashCode * 397) ^ this.B; |
|||
return hashCode; |
|||
} |
|||
} |
|||
|
|||
public void PackFromBytes(byte x, byte y, byte z, byte w) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public void PackFromVector4(Vector4 vector) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public Vector4 ToVector4() |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public void ToXyzBytes(Span<byte> bytes, int startIndex) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public void ToXyzwBytes(Span<byte> bytes, int startIndex) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public void ToZyxBytes(Span<byte> bytes, int startIndex) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
public void ToZyxwBytes(Span<byte> bytes, int startIndex) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,63 @@ |
|||
namespace ImageSharp.Tests |
|||
{ |
|||
using ImageSharp.PixelFormats; |
|||
|
|||
using Xunit; |
|||
|
|||
public class Bgr24Tests |
|||
{ |
|||
public static readonly TheoryData<byte, byte, byte> ColorData = |
|||
new TheoryData<byte, byte, byte>() { { 1, 2, 3 }, { 4, 5, 6 }, { 0, 255, 42 } }; |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(ColorData))] |
|||
public void Constructor(byte r, byte g, byte b) |
|||
{ |
|||
var p = new Rgb24(r, g, b); |
|||
|
|||
Assert.Equal(r, p.R); |
|||
Assert.Equal(g, p.G); |
|||
Assert.Equal(b, p.B); |
|||
} |
|||
[Fact] |
|||
public unsafe void ByteLayoutIsSequentialBgr() |
|||
{ |
|||
var color = new Bgr24(1, 2, 3); |
|||
byte* ptr = (byte*)&color; |
|||
|
|||
Assert.Equal(3, ptr[0]); |
|||
Assert.Equal(2, ptr[1]); |
|||
Assert.Equal(1, ptr[2]); |
|||
} |
|||
|
|||
public class Equality |
|||
{ |
|||
public static TheoryData<byte, byte, byte> ColorData = Rgb24Tests.ColorData; |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(ColorData))] |
|||
public void WhenTrue(byte r, byte g, byte b) |
|||
{ |
|||
var x = new Rgb24(r, g, b); |
|||
var y = new Rgb24(r, g, b); |
|||
|
|||
Assert.True(x.Equals(y)); |
|||
Assert.True(x.Equals((object)y)); |
|||
Assert.Equal(x.GetHashCode(), y.GetHashCode()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(1, 2, 3, 1, 2, 4)] |
|||
[InlineData(0, 255, 0, 0, 244, 0)] |
|||
[InlineData(1, 255, 0, 0, 255, 0)] |
|||
public void WhenFalse(byte r1, byte g1, byte b1, byte r2, byte g2, byte b2) |
|||
{ |
|||
var a = new Rgb24(1, 2, 3); |
|||
var b = new Rgb24(1, 2, 4); |
|||
|
|||
Assert.False(a.Equals(b)); |
|||
Assert.False(a.Equals((object)b)); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,50 @@ |
|||
// <copyright file="PixelBlenderTests.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageSharp.Tests.PixelFormats |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using ImageSharp.PixelFormats; |
|||
using ImageSharp.PixelFormats.PixelBlenders; |
|||
using ImageSharp.Tests.TestUtilities; |
|||
using Xunit; |
|||
|
|||
public partial class PixelOperationsTests |
|||
{ |
|||
public static TheoryData<object, Type, PixelBlenderMode> BlenderMappings = new TheoryData<object, Type, PixelBlenderMode>() |
|||
{ |
|||
{ new TestPixel<Rgba32>(), typeof(DefaultNormalPixelBlender<Rgba32>), PixelBlenderMode.Normal }, |
|||
{ new TestPixel<Rgba32>(), typeof(DefaultScreenPixelBlender<Rgba32>), PixelBlenderMode.Screen }, |
|||
{ new TestPixel<Rgba32>(), typeof(DefaultHardLightPixelBlender<Rgba32>), PixelBlenderMode.HardLight }, |
|||
{ new TestPixel<Rgba32>(), typeof(DefaultOverlayPixelBlender<Rgba32>), PixelBlenderMode.Overlay }, |
|||
{ new TestPixel<Rgba32>(), typeof(DefaultDarkenPixelBlender<Rgba32>), PixelBlenderMode.Darken }, |
|||
{ new TestPixel<Rgba32>(), typeof(DefaultLightenPixelBlender<Rgba32>), PixelBlenderMode.Lighten }, |
|||
{ new TestPixel<Rgba32>(), typeof(DefaultAddPixelBlender<Rgba32>), PixelBlenderMode.Add }, |
|||
{ new TestPixel<Rgba32>(), typeof(DefaultSubstractPixelBlender<Rgba32>), PixelBlenderMode.Substract }, |
|||
{ new TestPixel<Rgba32>(), typeof(DefaultMultiplyPixelBlender<Rgba32>), PixelBlenderMode.Multiply }, |
|||
|
|||
{ new TestPixel<RgbaVector>(), typeof(DefaultNormalPixelBlender<RgbaVector>), PixelBlenderMode.Normal }, |
|||
{ new TestPixel<RgbaVector>(), typeof(DefaultScreenPixelBlender<RgbaVector>), PixelBlenderMode.Screen }, |
|||
{ new TestPixel<RgbaVector>(), typeof(DefaultHardLightPixelBlender<RgbaVector>), PixelBlenderMode.HardLight }, |
|||
{ new TestPixel<RgbaVector>(), typeof(DefaultOverlayPixelBlender<RgbaVector>), PixelBlenderMode.Overlay }, |
|||
{ new TestPixel<RgbaVector>(), typeof(DefaultDarkenPixelBlender<RgbaVector>), PixelBlenderMode.Darken }, |
|||
{ new TestPixel<RgbaVector>(), typeof(DefaultLightenPixelBlender<RgbaVector>), PixelBlenderMode.Lighten }, |
|||
{ new TestPixel<RgbaVector>(), typeof(DefaultAddPixelBlender<RgbaVector>), PixelBlenderMode.Add }, |
|||
{ new TestPixel<RgbaVector>(), typeof(DefaultSubstractPixelBlender<RgbaVector>), PixelBlenderMode.Substract }, |
|||
{ new TestPixel<RgbaVector>(), typeof(DefaultMultiplyPixelBlender<RgbaVector>), PixelBlenderMode.Multiply }, |
|||
}; |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(BlenderMappings))] |
|||
public void ReturnsCorrectBlender<TPixel>(TestPixel<TPixel> pixel, Type type, PixelBlenderMode mode) |
|||
where TPixel : struct, IPixel<TPixel> |
|||
{ |
|||
PixelBlender<TPixel> blender = PixelOperations<TPixel>.Instance.GetPixelBlender(mode); |
|||
Assert.IsType(type, blender); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
// ReSharper disable InconsistentNaming
|
|||
namespace ImageSharp.Tests |
|||
{ |
|||
using ImageSharp.PixelFormats; |
|||
|
|||
using Xunit; |
|||
|
|||
public class Rgb24Tests |
|||
{ |
|||
public static readonly TheoryData<byte, byte, byte> ColorData = |
|||
new TheoryData<byte, byte, byte>() { { 1, 2, 3 }, { 4, 5, 6 }, { 0, 255, 42 } }; |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(ColorData))] |
|||
public void Constructor(byte r, byte g, byte b) |
|||
{ |
|||
var p = new Rgb24(r, g, b); |
|||
|
|||
Assert.Equal(r, p.R); |
|||
Assert.Equal(g, p.G); |
|||
Assert.Equal(b, p.B); |
|||
} |
|||
|
|||
[Fact] |
|||
public unsafe void ByteLayoutIsSequentialRgb() |
|||
{ |
|||
var color = new Rgb24(1, 2, 3); |
|||
byte* ptr = (byte*)&color; |
|||
|
|||
Assert.Equal(1, ptr[0]); |
|||
Assert.Equal(2, ptr[1]); |
|||
Assert.Equal(3, ptr[2]); |
|||
} |
|||
|
|||
public class Equality |
|||
{ |
|||
public static TheoryData<byte, byte, byte> ColorData = Rgb24Tests.ColorData; |
|||
|
|||
[Theory] |
|||
[MemberData(nameof(ColorData))] |
|||
public void WhenTrue(byte r, byte g, byte b) |
|||
{ |
|||
var x = new Rgb24(r, g, b); |
|||
var y = new Rgb24(r, g, b); |
|||
|
|||
Assert.True(x.Equals(y)); |
|||
Assert.True(x.Equals((object)y)); |
|||
Assert.Equal(x.GetHashCode(), y.GetHashCode()); |
|||
} |
|||
|
|||
[Theory] |
|||
[InlineData(1, 2, 3, 1, 2, 4)] |
|||
[InlineData(0, 255, 0, 0, 244, 0)] |
|||
[InlineData(1, 255, 0, 0, 255, 0)] |
|||
public void WhenFalse(byte r1, byte g1, byte b1, byte r2, byte g2, byte b2) |
|||
{ |
|||
var a = new Rgb24(1, 2, 3); |
|||
var b = new Rgb24(1, 2, 4); |
|||
|
|||
Assert.False(a.Equals(b)); |
|||
Assert.False(a.Equals((object)b)); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue