diff --git a/.editorconfig b/.editorconfig
index c28089d72..f579ff5d3 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -104,8 +104,8 @@ dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:war
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:warning
dotnet_style_parentheses_in_other_operators = always_for_clarity:suggestion
# Expression-level preferences
-dotnet_style_object_initializer = true:warning
-dotnet_style_collection_initializer = true:warning
+dotnet_style_object_initializer = true:error
+dotnet_style_collection_initializer = true:error
dotnet_style_explicit_tuple_names = true:warning
dotnet_style_prefer_inferred_tuple_names = true:warning
dotnet_style_prefer_inferred_anonymous_type_member_names = true:warning
@@ -135,9 +135,9 @@ csharp_style_prefer_null_check_over_type_check = true:warning
# https://docs.microsoft.com/dotnet/fundamentals/code-analysis/style-rules/language-rules#c-style-rules
[*.{cs,csx,cake}]
# 'var' preferences
-csharp_style_var_for_built_in_types = false:warning
-csharp_style_var_when_type_is_apparent = false:warning
-csharp_style_var_elsewhere = false:warning
+csharp_style_var_for_built_in_types = false:error
+csharp_style_var_when_type_is_apparent = false:error
+csharp_style_var_elsewhere = false:error
# Expression-bodied members
csharp_style_expression_bodied_methods = true:warning
csharp_style_expression_bodied_constructors = true:warning
@@ -160,7 +160,10 @@ csharp_style_pattern_local_over_anonymous_function = true:warning
csharp_style_deconstructed_variable_declaration = true:warning
csharp_style_prefer_index_operator = true:warning
csharp_style_prefer_range_operator = true:warning
-csharp_style_implicit_object_creation_when_type_is_apparent = true:warning
+csharp_style_implicit_object_creation_when_type_is_apparent = true:error
+# ReSharper inspection severities
+resharper_arrange_object_creation_when_type_evident_highlighting = error
+resharper_arrange_object_creation_when_type_not_evident_highlighting = error
# "Null" checking preferences
csharp_style_throw_expression = true:warning
csharp_style_conditional_delegate_call = true:warning
@@ -174,6 +177,9 @@ csharp_using_directive_placement = outside_namespace:warning
csharp_prefer_static_local_function = true:warning
# Primary constructor preferences
csharp_style_prefer_primary_constructors = false:none
+# Collection preferences
+dotnet_style_prefer_collection_expression = true:error
+resharper_use_collection_expression_highlighting =true:error
##########################################
# Unnecessary Code Rules
diff --git a/.gitattributes b/.gitattributes
index b5f742ab4..f7bd4d061 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -136,3 +136,10 @@
*.ico filter=lfs diff=lfs merge=lfs -text
*.cur filter=lfs diff=lfs merge=lfs -text
*.ani filter=lfs diff=lfs merge=lfs -text
+*.heic filter=lfs diff=lfs merge=lfs -text
+*.hif filter=lfs diff=lfs merge=lfs -text
+*.avif filter=lfs diff=lfs merge=lfs -text
+###############################################################################
+# Handle ICC files by git lfs
+###############################################################################
+*.icc filter=lfs diff=lfs merge=lfs -text
diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
index cb90793e0..ff3d5c7b0 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -11,35 +11,79 @@ on:
branches:
- main
- release/*
- types: [ labeled, opened, synchronize, reopened ]
+ types: [ opened, synchronize, reopened ]
+
jobs:
+ # Prime a single LFS cache and expose the exact key for the matrix
+ WarmLFS:
+ runs-on: ubuntu-latest
+ outputs:
+ lfs_key: ${{ steps.expose-key.outputs.lfs_key }}
+ steps:
+ - name: Git Config
+ shell: bash
+ run: |
+ git config --global core.autocrlf false
+ git config --global core.longpaths true
+
+ - name: Git Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ submodules: recursive
+
+ # Deterministic list of LFS object IDs, then compute a portable key:
+ # - `git lfs ls-files -l` lists all tracked LFS objects with their SHA-256
+ # - `awk '{print $1}'` extracts just the SHA field
+ # - `sort` sorts in byte order (hex hashes sort the same everywhere)
+ # This ensures the file content is identical regardless of OS or locale
+ - name: Git Create LFS id list
+ shell: bash
+ run: git lfs ls-files -l | awk '{print $1}' | sort > .lfs-assets-id
+
+ - name: Git Expose LFS cache key
+ id: expose-key
+ shell: bash
+ env:
+ LFS_KEY: lfs-${{ hashFiles('.lfs-assets-id') }}-v1
+ run: echo "lfs_key=$LFS_KEY" >> "$GITHUB_OUTPUT"
+
+ - name: Git Setup LFS Cache
+ uses: actions/cache@v4
+ with:
+ path: .git/lfs
+ key: ${{ steps.expose-key.outputs.lfs_key }}
+
+ - name: Git Pull LFS
+ shell: bash
+ run: git lfs pull
+
Build:
+ needs: WarmLFS
strategy:
matrix:
- isARM:
- - ${{ contains(github.event.pull_request.labels.*.name, 'arch:arm32') || contains(github.event.pull_request.labels.*.name, 'arch:arm64') }}
options:
- os: ubuntu-latest
- framework: net9.0
- sdk: 9.0.x
+ framework: net10.0
+ sdk: 10.0.x
sdk-preview: true
runtime: -x64
codecov: false
- - os: macos-13 # macos-latest runs on arm64 runners where libgdiplus is unavailable
- framework: net9.0
- sdk: 9.0.x
+ - os: macos-26
+ framework: net10.0
+ sdk: 10.0.x
sdk-preview: true
runtime: -x64
codecov: false
- os: windows-latest
- framework: net9.0
- sdk: 9.0.x
+ framework: net10.0
+ sdk: 10.0.x
sdk-preview: true
runtime: -x64
codecov: false
- - os: buildjet-4vcpu-ubuntu-2204-arm
- framework: net9.0
- sdk: 9.0.x
+ - os: ubuntu-22.04-arm
+ framework: net10.0
+ sdk: 10.0.x
sdk-preview: true
runtime: -x64
codecov: false
@@ -49,7 +93,7 @@ jobs:
sdk: 8.0.x
runtime: -x64
codecov: false
- - os: macos-13 # macos-latest runs on arm64 runners where libgdiplus is unavailable
+ - os: macos-26
framework: net8.0
sdk: 8.0.x
runtime: -x64
@@ -59,24 +103,32 @@ jobs:
sdk: 8.0.x
runtime: -x64
codecov: false
- - os: buildjet-4vcpu-ubuntu-2204-arm
+ - os: ubuntu-22.04-arm
framework: net8.0
sdk: 8.0.x
runtime: -x64
codecov: false
- exclude:
- - isARM: false
- options:
- os: buildjet-4vcpu-ubuntu-2204-arm
- runs-on: ${{matrix.options.os}}
+ runs-on: ${{ matrix.options.os }}
steps:
- name: Install libgdi+, which is required for tests running on ubuntu
if: ${{ contains(matrix.options.os, 'ubuntu') }}
run: |
- sudo apt-get update
- sudo apt-get -y install libgdiplus libgif-dev libglib2.0-dev libcairo2-dev libtiff-dev libexif-dev
+ sudo apt-get update
+ sudo apt-get -y install libgdiplus libgif-dev libglib2.0-dev libcairo2-dev libtiff-dev libexif-dev
+
+ - name: Install libgdi+, which is required for tests running on macos
+ if: ${{ contains(matrix.options.os, 'macos-26') }}
+ run: |
+ brew update
+ brew install mono-libgdiplus
+ # Create symlinks to make libgdiplus discoverable
+ sudo mkdir -p /usr/local/lib
+ sudo ln -sf $(brew --prefix)/lib/libgdiplus.dylib /usr/local/lib/libgdiplus.dylib
+ # Verify installation
+ ls -la $(brew --prefix)/lib/libgdiplus* || echo "libgdiplus not found in brew prefix"
+ ls -la /usr/local/lib/libgdiplus* || echo "libgdiplus not found in /usr/local/lib"
- name: Git Config
shell: bash
@@ -90,18 +142,15 @@ jobs:
fetch-depth: 0
submodules: recursive
- # See https://github.com/actions/checkout/issues/165#issuecomment-657673315
- - name: Git Create LFS FileList
- run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id
-
+ # Use the warmed key from WarmLFS. Do not recompute or recreate .lfs-assets-id here.
- name: Git Setup LFS Cache
uses: actions/cache@v4
- id: lfs-cache
with:
path: .git/lfs
- key: ${{ runner.os }}-lfs-${{ hashFiles('.lfs-assets-id') }}-v1
+ key: ${{ needs.WarmLFS.outputs.lfs_key }}
- name: Git Pull LFS
+ shell: bash
run: git lfs pull
- name: NuGet Install
@@ -127,7 +176,7 @@ jobs:
uses: actions/setup-dotnet@v4
with:
dotnet-version: |
- 9.0.x
+ 10.0.x
- name: DotNet Build
if: ${{ matrix.options.sdk-preview != true }}
@@ -168,11 +217,8 @@ jobs:
Publish:
needs: [Build]
-
runs-on: ubuntu-latest
-
if: (github.event_name == 'push')
-
steps:
- name: Git Config
shell: bash
@@ -213,4 +259,3 @@ jobs:
run: |
dotnet nuget push .\artifacts\*.nupkg -k ${{secrets.NUGET_TOKEN}} -s https://api.nuget.org/v3/index.json --skip-duplicate
dotnet nuget push .\artifacts\*.snupkg -k ${{secrets.NUGET_TOKEN}} -s https://api.nuget.org/v3/index.json --skip-duplicate
-
diff --git a/.github/workflows/code-coverage.yml b/.github/workflows/code-coverage.yml
index b4965795c..07ce0408f 100644
--- a/.github/workflows/code-coverage.yml
+++ b/.github/workflows/code-coverage.yml
@@ -4,6 +4,7 @@ on:
schedule:
# 2AM every Tuesday/Thursday
- cron: "0 2 * * 2,4"
+
jobs:
Build:
strategy:
@@ -14,15 +15,14 @@ jobs:
runtime: -x64
codecov: true
- runs-on: ${{matrix.options.os}}
+ runs-on: ${{ matrix.options.os }}
steps:
-
- name: Install libgdi+, which is required for tests running on ubuntu
if: ${{ contains(matrix.options.os, 'ubuntu') }}
run: |
- sudo apt-get update
- sudo apt-get -y install libgdiplus libgif-dev libglib2.0-dev libcairo2-dev libtiff-dev libexif-dev
+ sudo apt-get update
+ sudo apt-get -y install libgdiplus libgif-dev libglib2.0-dev libcairo2-dev libtiff-dev libexif-dev
- name: Git Config
shell: bash
@@ -36,16 +36,21 @@ jobs:
fetch-depth: 0
submodules: recursive
- # See https://github.com/actions/checkout/issues/165#issuecomment-657673315
- - name: Git Create LFS FileList
- run: git lfs ls-files -l | cut -d' ' -f1 | sort > .lfs-assets-id
+ # Deterministic list of LFS object IDs, then compute a portable key:
+ # - `git lfs ls-files -l` lists all tracked LFS objects with their SHA-256
+ # - `awk '{print $1}'` extracts just the SHA field
+ # - `sort` sorts in byte order (hex hashes sort the same everywhere)
+ # This ensures the file content is identical regardless of OS or locale
+ - name: Git Create LFS id list
+ shell: bash
+ run: git lfs ls-files -l | awk '{print $1}' | sort > .lfs-assets-id
- name: Git Setup LFS Cache
uses: actions/cache@v4
id: lfs-cache
with:
path: .git/lfs
- key: ${{ runner.os }}-lfs-${{ hashFiles('.lfs-assets-id') }}-v1
+ key: lfs-${{ hashFiles('.lfs-assets-id') }}-v1
- name: Git Pull LFS
run: git lfs pull
@@ -69,13 +74,13 @@ jobs:
- name: DotNet Build
shell: pwsh
- run: ./ci-build.ps1 "${{matrix.options.framework}}"
+ run: ./ci-build.ps1 "${{ matrix.options.framework }}"
env:
SIXLABORS_TESTING: True
- name: DotNet Test
shell: pwsh
- run: ./ci-test.ps1 "${{matrix.options.os}}" "${{matrix.options.framework}}" "${{matrix.options.runtime}}" "${{matrix.options.codecov}}"
+ run: ./ci-test.ps1 "${{ matrix.options.os }}" "${{ matrix.options.framework }}" "${{ matrix.options.runtime }}" "${{ matrix.options.codecov }}"
env:
SIXLABORS_TESTING: True
XUNIT_PATH: .\tests\ImageSharp.Tests # Required for xunit
@@ -88,7 +93,8 @@ jobs:
path: tests/Images/ActualOutput/
- name: Codecov Update
- uses: codecov/codecov-action@v4
+ uses: codecov/codecov-action@v5
if: matrix.options.codecov == true && startsWith(github.repository, 'SixLabors')
with:
flags: unittests
+ token: ${{ secrets.CODECOV_TOKEN }}
diff --git a/Directory.Build.props b/Directory.Build.props
index 755cbe3b3..9bda76f88 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -21,10 +21,14 @@
-
+
12.0
+
+ 14.0
+
+
-
+
diff --git a/tests/ImageSharp.Benchmarks/Bulk/FromVector4.cs b/tests/ImageSharp.Benchmarks/Bulk/FromVector4.cs
index 53c26a57e..80b096344 100644
--- a/tests/ImageSharp.Benchmarks/Bulk/FromVector4.cs
+++ b/tests/ImageSharp.Benchmarks/Bulk/FromVector4.cs
@@ -73,7 +73,8 @@ public class FromVector4Rgba32 : FromVector4
SimdUtils.HwIntrinsics.NormalizedFloatToByteSaturate(sBytes, dFloats);
}
- private static ReadOnlySpan PermuteMaskDeinterleave8x32 => new byte[] { 0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0 };
+ private static ReadOnlySpan PermuteMaskDeinterleave8x32 => [0, 0, 0, 0, 4, 0, 0, 0, 1, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 6, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0
+ ];
[Benchmark]
public void UseAvx2_Grouped()
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Bmp/EncodeBmpMultiple.cs b/tests/ImageSharp.Benchmarks/Codecs/Bmp/EncodeBmpMultiple.cs
index fdef1b2bf..ce54c133b 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Bmp/EncodeBmpMultiple.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Bmp/EncodeBmpMultiple.cs
@@ -10,7 +10,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs;
[Config(typeof(Config.Short))]
public class EncodeBmpMultiple : MultiImageBenchmarkBase.WithImagesPreloaded
{
- protected override IEnumerable InputImageSubfoldersOrFiles => new[] { "Bmp/", "Jpg/baseline" };
+ protected override IEnumerable InputImageSubfoldersOrFiles => ["Bmp/", "Jpg/baseline"];
[Benchmark(Description = "EncodeBmpMultiple - ImageSharp")]
public void EncodeBmpImageSharp()
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Gif/DecodeEncodeGif.cs b/tests/ImageSharp.Benchmarks/Codecs/Gif/DecodeEncodeGif.cs
new file mode 100644
index 000000000..3238e8dac
--- /dev/null
+++ b/tests/ImageSharp.Benchmarks/Codecs/Gif/DecodeEncodeGif.cs
@@ -0,0 +1,59 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Drawing.Imaging;
+using BenchmarkDotNet.Attributes;
+using SixLabors.ImageSharp.Formats.Gif;
+using SixLabors.ImageSharp.Processing;
+using SixLabors.ImageSharp.Processing.Processors.Quantization;
+using SixLabors.ImageSharp.Tests;
+using SDImage = System.Drawing.Image;
+
+namespace SixLabors.ImageSharp.Benchmarks.Codecs;
+
+public abstract class DecodeEncodeGif
+{
+ private MemoryStream outputStream;
+
+ protected abstract GifEncoder Encoder { get; }
+
+ [Params(TestImages.Gif.Leo, TestImages.Gif.Cheers)]
+ public string TestImage { get; set; }
+
+ private string TestImageFullPath => Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage);
+
+ [GlobalSetup]
+ public void Setup() => this.outputStream = new MemoryStream();
+
+ [GlobalCleanup]
+ public void Cleanup() => this.outputStream.Close();
+
+ [Benchmark(Baseline = true)]
+ public void SystemDrawing()
+ {
+ this.outputStream.Position = 0;
+ using SDImage image = SDImage.FromFile(this.TestImageFullPath);
+ image.Save(this.outputStream, ImageFormat.Gif);
+ }
+
+ [Benchmark]
+ public void ImageSharp()
+ {
+ this.outputStream.Position = 0;
+ using Image image = Image.Load(this.TestImageFullPath);
+ image.SaveAsGif(this.outputStream, this.Encoder);
+ }
+}
+
+public class DecodeEncodeGif_DefaultEncoder : DecodeEncodeGif
+{
+ protected override GifEncoder Encoder => new();
+}
+
+public class DecodeEncodeGif_CoarsePaletteEncoder : DecodeEncodeGif
+{
+ protected override GifEncoder Encoder => new()
+ {
+ Quantizer = new WebSafePaletteQuantizer(new QuantizerOptions { Dither = KnownDitherings.Bayer4x4, ColorMatchingMode = ColorMatchingMode.Coarse })
+ };
+}
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Gif/EncodeGif.cs b/tests/ImageSharp.Benchmarks/Codecs/Gif/EncodeGif.cs
index beedbbe07..b8f8f7851 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Gif/EncodeGif.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Gif/EncodeGif.cs
@@ -3,6 +3,7 @@
using System.Drawing.Imaging;
using BenchmarkDotNet.Attributes;
+using ImageMagick;
using SixLabors.ImageSharp.Formats.Gif;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
@@ -12,21 +13,17 @@ using SDImage = System.Drawing.Image;
namespace SixLabors.ImageSharp.Benchmarks.Codecs;
-[Config(typeof(Config.Short))]
-public class EncodeGif
+public abstract class EncodeGif
{
// System.Drawing needs this.
private FileStream bmpStream;
private SDImage bmpDrawing;
private Image bmpCore;
+ private MagickImageCollection magickImage;
- // Try to get as close to System.Drawing's output as possible
- private readonly GifEncoder encoder = new()
- {
- Quantizer = new WebSafePaletteQuantizer(new QuantizerOptions { Dither = KnownDitherings.Bayer4x4 })
- };
+ protected abstract GifEncoder Encoder { get; }
- [Params(TestImages.Bmp.Car, TestImages.Png.Rgb48Bpp)]
+ [Params(TestImages.Gif.Leo, TestImages.Gif.Cheers)]
public string TestImage { get; set; }
[GlobalSetup]
@@ -34,10 +31,14 @@ public class EncodeGif
{
if (this.bmpStream == null)
{
- this.bmpStream = File.OpenRead(Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage));
+ string filePath = Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, this.TestImage);
+ this.bmpStream = File.OpenRead(filePath);
this.bmpCore = Image.Load(this.bmpStream);
this.bmpStream.Position = 0;
this.bmpDrawing = SDImage.FromStream(this.bmpStream);
+
+ this.bmpStream.Position = 0;
+ this.magickImage = new MagickImageCollection(this.bmpStream);
}
}
@@ -48,6 +49,7 @@ public class EncodeGif
this.bmpStream = null;
this.bmpCore.Dispose();
this.bmpDrawing.Dispose();
+ this.magickImage.Dispose();
}
[Benchmark(Baseline = true, Description = "System.Drawing Gif")]
@@ -61,6 +63,26 @@ public class EncodeGif
public void GifImageSharp()
{
using MemoryStream memoryStream = new();
- this.bmpCore.SaveAsGif(memoryStream, this.encoder);
+ this.bmpCore.SaveAsGif(memoryStream, this.Encoder);
}
+
+ [Benchmark(Description = "Magick.NET Gif")]
+ public void GifMagickNet()
+ {
+ using MemoryStream ms = new();
+ this.magickImage.Write(ms, MagickFormat.Gif);
+ }
+}
+
+public class EncodeGif_DefaultEncoder : EncodeGif
+{
+ protected override GifEncoder Encoder => new();
+}
+
+public class EncodeGif_CoarsePaletteEncoder : EncodeGif
+{
+ protected override GifEncoder Encoder => new()
+ {
+ Quantizer = new WebSafePaletteQuantizer(new QuantizerOptions { Dither = KnownDitherings.Bayer4x4, ColorMatchingMode = ColorMatchingMode.Coarse })
+ };
}
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Gif/EncodeGifMultiple.cs b/tests/ImageSharp.Benchmarks/Codecs/Gif/EncodeGifMultiple.cs
index 303272837..1eca07ec7 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Gif/EncodeGifMultiple.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Gif/EncodeGifMultiple.cs
@@ -15,7 +15,7 @@ public class EncodeGifMultiple : MultiImageBenchmarkBase.WithImagesPreloaded
[Params(InputImageCategory.AllImages)]
public override InputImageCategory InputCategory { get; set; }
- protected override IEnumerable InputImageSubfoldersOrFiles => new[] { "Gif/" };
+ protected override IEnumerable InputImageSubfoldersOrFiles => ["Gif/"];
[Benchmark(Description = "EncodeGifMultiple - ImageSharp")]
public void EncodeGifImageSharp()
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs
index 72b6bb72e..4ea0a92f1 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_CopyTo2x2.cs
@@ -185,15 +185,15 @@ public class Block8x8F_CopyTo2x2
ref Vector2 dBottomLeft = ref Unsafe.Add(ref dTopLeft, (uint)destStride);
ref Vector2 dBottomRight = ref Unsafe.Add(ref dBottomLeft, 4);
- var xLeft = new Vector2(sLeft.X);
- var yLeft = new Vector2(sLeft.Y);
- var zLeft = new Vector2(sLeft.Z);
- var wLeft = new Vector2(sLeft.W);
+ Vector2 xLeft = new(sLeft.X);
+ Vector2 yLeft = new(sLeft.Y);
+ Vector2 zLeft = new(sLeft.Z);
+ Vector2 wLeft = new(sLeft.W);
- var xRight = new Vector2(sRight.X);
- var yRight = new Vector2(sRight.Y);
- var zRight = new Vector2(sRight.Z);
- var wRight = new Vector2(sRight.W);
+ Vector2 xRight = new(sRight.X);
+ Vector2 yRight = new(sRight.Y);
+ Vector2 zRight = new(sRight.Z);
+ Vector2 wRight = new(sRight.W);
dTopLeft = xLeft;
Unsafe.Add(ref dTopLeft, 1) = yLeft;
@@ -245,15 +245,15 @@ public class Block8x8F_CopyTo2x2
ref Vector2 dBottomLeft = ref Unsafe.Add(ref dTopLeft, (uint)destStride);
ref Vector2 dBottomRight = ref Unsafe.Add(ref dBottomLeft, 4);
- var xLeft = new Vector4(sLeft.X);
- var yLeft = new Vector4(sLeft.Y);
- var zLeft = new Vector4(sLeft.Z);
- var wLeft = new Vector4(sLeft.W);
+ Vector4 xLeft = new(sLeft.X);
+ Vector4 yLeft = new(sLeft.Y);
+ Vector4 zLeft = new(sLeft.Z);
+ Vector4 wLeft = new(sLeft.W);
- var xRight = new Vector4(sRight.X);
- var yRight = new Vector4(sRight.Y);
- var zRight = new Vector4(sRight.Z);
- var wRight = new Vector4(sRight.W);
+ Vector4 xRight = new(sRight.X);
+ Vector4 yRight = new(sRight.Y);
+ Vector4 zRight = new(sRight.Z);
+ Vector4 wRight = new(sRight.W);
Unsafe.As(ref dTopLeft) = xLeft;
Unsafe.As(ref Unsafe.Add(ref dTopLeft, 1)) = yLeft;
@@ -303,15 +303,15 @@ public class Block8x8F_CopyTo2x2
ref Vector2 dTopLeft = ref Unsafe.Add(ref destBase, (uint)(2 * row * destStride));
ref Vector2 dBottomLeft = ref Unsafe.Add(ref dTopLeft, (uint)destStride);
- var xLeft = new Vector4(sLeft.X);
- var yLeft = new Vector4(sLeft.Y);
- var zLeft = new Vector4(sLeft.Z);
- var wLeft = new Vector4(sLeft.W);
+ Vector4 xLeft = new(sLeft.X);
+ Vector4 yLeft = new(sLeft.Y);
+ Vector4 zLeft = new(sLeft.Z);
+ Vector4 wLeft = new(sLeft.W);
- var xRight = new Vector4(sRight.X);
- var yRight = new Vector4(sRight.Y);
- var zRight = new Vector4(sRight.Z);
- var wRight = new Vector2(sRight.W);
+ Vector4 xRight = new(sRight.X);
+ Vector4 yRight = new(sRight.Y);
+ Vector4 zRight = new(sRight.Z);
+ Vector2 wRight = new(sRight.W);
Unsafe.As(ref dTopLeft) = xLeft;
Unsafe.As(ref Unsafe.Add(ref dTopLeft, 1)) = yLeft;
@@ -362,25 +362,25 @@ public class Block8x8F_CopyTo2x2
ref Vector4 dTopLeft = ref Unsafe.As(ref Unsafe.Add(ref destBase, (uint)offset));
ref Vector4 dBottomLeft = ref Unsafe.As(ref Unsafe.Add(ref destBase, (uint)(offset + destStride)));
- var xyLeft = new Vector4(sLeft.X)
+ Vector4 xyLeft = new(sLeft.X)
{
Z = sLeft.Y,
W = sLeft.Y
};
- var zwLeft = new Vector4(sLeft.Z)
+ Vector4 zwLeft = new(sLeft.Z)
{
Z = sLeft.W,
W = sLeft.W
};
- var xyRight = new Vector4(sRight.X)
+ Vector4 xyRight = new(sRight.X)
{
Z = sRight.Y,
W = sRight.Y
};
- var zwRight = new Vector4(sRight.Z)
+ Vector4 zwRight = new(sRight.Z)
{
Z = sRight.W,
W = sRight.W
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_DivideRound.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_DivideRound.cs
index efc347586..45c6f63b9 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_DivideRound.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_DivideRound.cs
@@ -19,8 +19,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg.BlockOperations;
public unsafe class Block8x8F_DivideRound
{
private const int ExecutionCount = 5; // Added this to reduce the effect of copying the blocks
- private static readonly Vector4 MinusOne = new Vector4(-1);
- private static readonly Vector4 Half = new Vector4(0.5f);
+ private static readonly Vector4 MinusOne = new(-1);
+ private static readonly Vector4 Half = new(0.5f);
private Block8x8F inputDividend;
private Block8x8F inputDivisor;
@@ -140,7 +140,7 @@ public unsafe class Block8x8F_DivideRound
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static Vector4 DivideRound(Vector4 dividend, Vector4 divisor)
{
- var sign = Vector4.Min(dividend, Vector4.One);
+ Vector4 sign = Vector4.Min(dividend, Vector4.One);
sign = Vector4.Max(sign, MinusOne);
return (dividend / divisor) + (sign * Half);
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_LoadFromInt16.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_LoadFromInt16.cs
index 7a8502c2c..25b5e973e 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_LoadFromInt16.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_LoadFromInt16.cs
@@ -32,7 +32,7 @@ public class Block8x8F_LoadFromInt16
public void Scalar() => this.destination.LoadFromInt16Scalar(ref this.source);
[Benchmark]
- public void ExtendedAvx2() => this.destination.LoadFromInt16ExtendedAvx2(ref this.source);
+ public void ExtendedAvx2() => this.destination.LoadFromInt16ExtendedVector256(ref this.source);
// RESULT:
// Method | Mean | Error | StdDev | Scaled |
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_MultiplyInPlaceBlock.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_MultiplyInPlaceBlock.cs
index 722b09587..3c03f3e05 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_MultiplyInPlaceBlock.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_MultiplyInPlaceBlock.cs
@@ -20,7 +20,7 @@ public class Block8x8F_MultiplyInPlaceBlock
private static Block8x8F Create8x8FloatData()
{
- var result = new float[64];
+ float[] result = new float[64];
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Transpose.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Transpose.cs
index 07907f21d..caca630bc 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Transpose.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/BlockOperations/Block8x8F_Transpose.cs
@@ -14,7 +14,7 @@ public class Block8x8F_Transpose
[Benchmark]
public float TransposeInplace()
{
- this.source.TransposeInplace();
+ this.source.TransposeInPlace();
return this.source[0];
}
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs
index 9189bec37..a1ba3fb8d 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/CmykColorConversion.cs
@@ -17,32 +17,32 @@ public class CmykColorConversion : ColorConversionBenchmark
[Benchmark(Baseline = true)]
public void Scalar()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.CmykScalar(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.CmykScalar(8).ConvertToRgbInPlace(values);
}
[Benchmark]
- public void SimdVector8()
+ public void SimdVector128()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.CmykVector(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.CmykVector128(8).ConvertToRgbInPlace(values);
}
[Benchmark]
- public void SimdVectorAvx()
+ public void SimdVector256()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.CmykAvx(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.CmykVector256(8).ConvertToRgbInPlace(values);
}
[Benchmark]
- public void SimdVectorArm64()
+ public void SimdVector512()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.CmykArm64(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.CmykVector512(8).ConvertToRgbInPlace(values);
}
}
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/ColorConversionBenchmark.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/ColorConversionBenchmark.cs
index 8964667b7..436aa9bcd 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/ColorConversionBenchmark.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/ColorConversionBenchmark.cs
@@ -38,11 +38,11 @@ public abstract class ColorConversionBenchmark
float minVal = 0f,
float maxVal = 255f)
{
- var rnd = new Random(42);
- var buffers = new Buffer2D[componentCount];
+ Random rnd = new(42);
+ Buffer2D[] buffers = new Buffer2D[componentCount];
for (int i = 0; i < componentCount; i++)
{
- var values = new float[inputBufferLength];
+ float[] values = new float[inputBufferLength];
for (int j = 0; j < inputBufferLength; j++)
{
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs
index a1d85ef46..3ade4279f 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/GrayscaleColorConversion.cs
@@ -7,9 +7,9 @@ using SixLabors.ImageSharp.Formats.Jpeg.Components;
namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg;
[Config(typeof(Config.Short))]
-public class GrayscaleColorConversion : ColorConversionBenchmark
+public class GrayScaleColorConversion : ColorConversionBenchmark
{
- public GrayscaleColorConversion()
+ public GrayScaleColorConversion()
: base(1)
{
}
@@ -17,24 +17,32 @@ public class GrayscaleColorConversion : ColorConversionBenchmark
[Benchmark(Baseline = true)]
public void Scalar()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.GrayscaleScalar(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.GrayScaleScalar(8).ConvertToRgbInPlace(values);
}
[Benchmark]
- public void SimdVectorAvx()
+ public void SimdVector128()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.GrayscaleAvx(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.GrayScaleVector128(8).ConvertToRgbInPlace(values);
}
[Benchmark]
- public void SimdVectorArm()
+ public void SimdVector256()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.GrayscaleArm(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.GrayScaleVector256(8).ConvertToRgbInPlace(values);
+ }
+
+ [Benchmark]
+ public void SimdVector512()
+ {
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
+
+ new JpegColorConverterBase.GrayScaleVector512(8).ConvertToRgbInPlace(values);
}
}
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs
index 5e2b6fe86..2916dcdce 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/RgbColorConversion.cs
@@ -17,32 +17,32 @@ public class RgbColorConversion : ColorConversionBenchmark
[Benchmark(Baseline = true)]
public void Scalar()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.RgbScalar(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.RgbScalar(8).ConvertToRgbInPlace(values);
}
[Benchmark]
- public void SimdVector8()
+ public void SimdVector128()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.RgbVector(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.RgbVector128(8).ConvertToRgbInPlace(values);
}
[Benchmark]
- public void SimdVectorAvx()
+ public void SimdVector256()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.RgbAvx(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.RgbVector256(8).ConvertToRgbInPlace(values);
}
[Benchmark]
- public void SimdVectorArm()
+ public void SimdVector512()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.RgbArm(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.RgbVector512(8).ConvertToRgbInPlace(values);
}
}
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs
index f8621c250..fbd762af4 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YCbCrColorConversion.cs
@@ -17,32 +17,32 @@ public class YCbCrColorConversion : ColorConversionBenchmark
[Benchmark]
public void Scalar()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.YCbCrScalar(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.YCbCrScalar(8).ConvertToRgbInPlace(values);
}
[Benchmark]
- public void SimdVector8()
+ public void SimdVector128()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.YCbCrVector(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.YCbCrVector128(8).ConvertToRgbInPlace(values);
}
[Benchmark]
- public void SimdVectorAvx()
+ public void SimdVector256()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.YCbCrAvx(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.YCbCrVector256(8).ConvertToRgbInPlace(values);
}
[Benchmark]
- public void SimdVectorArm()
+ public void SimdVector512()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.YCbCrArm(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.YCbCrVector512(8).ConvertToRgbInPlace(values);
}
}
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs
index a414b6ed4..e6b04c152 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/ColorConversion/YccKColorConverter.cs
@@ -17,32 +17,32 @@ public class YccKColorConverter : ColorConversionBenchmark
[Benchmark(Baseline = true)]
public void Scalar()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.YccKScalar(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.YccKScalar(8).ConvertToRgbInPlace(values);
}
[Benchmark]
- public void SimdVector8()
+ public void SimdVector128()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.YccKVector(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.YccKVector128(8).ConvertToRgbInPlace(values);
}
[Benchmark]
- public void SimdVectorAvx2()
+ public void SimdVector256()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.YccKAvx(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.YccKVector256(8).ConvertToRgbInPlace(values);
}
[Benchmark]
- public void SimdVectorArm64()
+ public void SimdVector512()
{
- var values = new JpegColorConverterBase.ComponentValues(this.Input, 0);
+ JpegColorConverterBase.ComponentValues values = new(this.Input, 0);
- new JpegColorConverterBase.YccKArm64(8).ConvertToRgbInplace(values);
+ new JpegColorConverterBase.YccKVector512(8).ConvertToRgbInPlace(values);
}
}
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs
index 0dc6d26bc..dbd255722 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs
@@ -8,6 +8,7 @@ using SixLabors.ImageSharp.Tests;
namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg;
+[Config(typeof(Config.HwIntrinsics_SSE_AVX))]
public class DecodeJpeg
{
private JpegDecoder decoder;
@@ -21,7 +22,7 @@ public class DecodeJpeg
this.preloadedImageStream = new MemoryStream(bytes);
}
- private void GenericBechmark()
+ private void GenericBenchmark()
{
this.preloadedImageStream.Position = 0;
using Image img = this.decoder.Decode(DecoderOptions.Default, this.preloadedImageStream);
@@ -51,16 +52,16 @@ public class DecodeJpeg
}
[Benchmark(Description = "Baseline 4:4:4 Interleaved")]
- public void JpegBaselineInterleaved444() => this.GenericBechmark();
+ public void JpegBaselineInterleaved444() => this.GenericBenchmark();
[Benchmark(Description = "Baseline 4:2:0 Interleaved")]
- public void JpegBaselineInterleaved420() => this.GenericBechmark();
+ public void JpegBaselineInterleaved420() => this.GenericBenchmark();
[Benchmark(Description = "Baseline 4:0:0 (grayscale)")]
- public void JpegBaseline400() => this.GenericBechmark();
+ public void JpegBaseline400() => this.GenericBenchmark();
[Benchmark(Description = "Progressive 4:2:0 Non-Interleaved")]
- public void JpegProgressiveNonInterleaved420() => this.GenericBechmark();
+ public void JpegProgressiveNonInterleaved420() => this.GenericBenchmark();
}
/*
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegParseStreamOnly.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegParseStreamOnly.cs
index 5f6dbbdf7..e7b66576d 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegParseStreamOnly.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegParseStreamOnly.cs
@@ -2,9 +2,11 @@
// Licensed under the Six Labors Split License.
using BenchmarkDotNet.Attributes;
+using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder;
using SixLabors.ImageSharp.IO;
+using SixLabors.ImageSharp.Metadata.Profiles.Icc;
using SixLabors.ImageSharp.Tests;
using SDSize = System.Drawing.Size;
@@ -37,7 +39,7 @@ public class DecodeJpegParseStreamOnly
{
using MemoryStream memoryStream = new(this.jpegBytes);
using BufferedReadStream bufferedStream = new(Configuration.Default, memoryStream);
- JpegDecoderOptions options = new() { GeneralOptions = new() { SkipMetadata = true } };
+ JpegDecoderOptions options = new() { GeneralOptions = new DecoderOptions { SkipMetadata = true } };
using JpegDecoderCore decoder = new(options);
NoopSpectralConverter spectralConverter = new();
@@ -50,7 +52,7 @@ public class DecodeJpegParseStreamOnly
// There's no way to eliminate it as spectral conversion is built into the scan decoding loop for memory footprint reduction
private sealed class NoopSpectralConverter : SpectralConverter
{
- public override void ConvertStrideBaseline()
+ public override void ConvertStrideBaseline(IccProfile iccProfile)
{
}
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs
index 257e44cc4..9a4ee3967 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg_ImageSpecific.cs
@@ -49,7 +49,7 @@ public class DecodeJpeg_ImageSpecific
public Size ImageSharp()
{
using MemoryStream memoryStream = new(this.jpegBytes);
- using Image image = Image.Load(new DecoderOptions() { SkipMetadata = true }, memoryStream);
+ using Image image = Image.Load(new DecoderOptions { SkipMetadata = true }, memoryStream);
return new Size(image.Width, image.Height);
}
diff --git a/tests/ImageSharp.Benchmarks/Color/RgbWorkingSpaceAdapt.cs b/tests/ImageSharp.Benchmarks/Color/RgbWorkingSpaceAdapt.cs
index 6cd8df3fc..b847e3ac5 100644
--- a/tests/ImageSharp.Benchmarks/Color/RgbWorkingSpaceAdapt.cs
+++ b/tests/ImageSharp.Benchmarks/Color/RgbWorkingSpaceAdapt.cs
@@ -13,7 +13,7 @@ public class RgbWorkingSpaceAdapt
private static readonly RGBColor RGBColor = new(0.206162, 0.260277, 0.746717);
- private static readonly ColorProfileConverter ColorProfileConverter = new(new ColorConversionOptions { RgbWorkingSpace = KnownRgbWorkingSpaces.WideGamutRgb, TargetRgbWorkingSpace = KnownRgbWorkingSpaces.SRgb });
+ private static readonly ColorProfileConverter ColorProfileConverter = new(new ColorConversionOptions { SourceRgbWorkingSpace = KnownRgbWorkingSpaces.WideGamutRgb, TargetRgbWorkingSpace = KnownRgbWorkingSpaces.SRgb });
private static readonly IColorConverter ColourfulConverter = new ConverterBuilder().FromRGB(RGBWorkingSpaces.WideGamutRGB).ToRGB(RGBWorkingSpaces.sRGB).Build();
diff --git a/tests/ImageSharp.Benchmarks/Config.HwIntrinsics.cs b/tests/ImageSharp.Benchmarks/Config.HwIntrinsics.cs
index e21d0c76d..9fd48301e 100644
--- a/tests/ImageSharp.Benchmarks/Config.HwIntrinsics.cs
+++ b/tests/ImageSharp.Benchmarks/Config.HwIntrinsics.cs
@@ -34,6 +34,7 @@ public partial class Config
// like `LZCNT`, `BMI1`, or `BMI2`
// `EnableSSE3_4` is a legacy switch that exists for compat and is basically the same as `EnableSSE3`
private const string EnableAES = "DOTNET_EnableAES";
+ private const string EnableAVX512F = "DOTNET_EnableAVX512F";
private const string EnableAVX = "DOTNET_EnableAVX";
private const string EnableAVX2 = "DOTNET_EnableAVX2";
private const string EnableBMI1 = "DOTNET_EnableBMI1";
@@ -76,4 +77,36 @@ public partial class Config
}
}
}
+
+ public class HwIntrinsics_SSE_AVX_AVX512F : Config
+ {
+ public HwIntrinsics_SSE_AVX_AVX512F()
+ {
+ this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core80)
+ .WithEnvironmentVariables(
+ new EnvironmentVariable(EnableHWIntrinsic, Off),
+ new EnvironmentVariable(FeatureSIMD, Off))
+ .WithId("1. No HwIntrinsics").AsBaseline());
+
+ if (Sse.IsSupported)
+ {
+ this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core80)
+ .WithEnvironmentVariables(new EnvironmentVariable(EnableAVX, Off))
+ .WithId("2. SSE"));
+ }
+
+ if (Avx.IsSupported)
+ {
+ this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core80)
+ .WithEnvironmentVariables(new EnvironmentVariable(EnableAVX512F, Off))
+ .WithId("3. AVX"));
+ }
+
+ if (Avx512F.IsSupported)
+ {
+ this.AddJob(Job.Default.WithRuntime(CoreRuntime.Core80)
+ .WithId("3. AVX512F"));
+ }
+ }
+ }
}
diff --git a/tests/ImageSharp.Benchmarks/Config.cs b/tests/ImageSharp.Benchmarks/Config.cs
index 190c245c9..9231fc8b4 100644
--- a/tests/ImageSharp.Benchmarks/Config.cs
+++ b/tests/ImageSharp.Benchmarks/Config.cs
@@ -10,6 +10,7 @@ using BenchmarkDotNet.Diagnosers;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Reports;
+using BenchmarkDotNet.Toolchains.InProcess.Emit;
namespace SixLabors.ImageSharp.Benchmarks;
@@ -45,6 +46,15 @@ public partial class Config : ManualConfig
.WithArguments([new MsBuildArgument("/p:DebugType=portable")]));
}
+ public class StandardInProcess : Config
+ {
+ public StandardInProcess() => this.AddJob(
+ Job.Default
+ .WithRuntime(CoreRuntime.Core80)
+ .WithToolchain(InProcessEmitToolchain.Instance)
+ .WithArguments([new MsBuildArgument("/p:DebugType=portable")]));
+ }
+
#if OS_WINDOWS
private bool IsElevated => new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
#endif
diff --git a/tests/ImageSharp.Benchmarks/General/Adler32Benchmark.cs b/tests/ImageSharp.Benchmarks/General/Adler32Benchmark.cs
index 30023feca..64a8092c6 100644
--- a/tests/ImageSharp.Benchmarks/General/Adler32Benchmark.cs
+++ b/tests/ImageSharp.Benchmarks/General/Adler32Benchmark.cs
@@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.Benchmarks.General;
public class Adler32Benchmark
{
private byte[] data;
- private readonly SharpAdler32 adler = new SharpAdler32();
+ private readonly SharpAdler32 adler = new();
[Params(1024, 2048, 4096)]
public int Count { get; set; }
diff --git a/tests/ImageSharp.Benchmarks/General/BasicMath/ClampFloat.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/ClampFloat.cs
index dd0bc2878..317295144 100644
--- a/tests/ImageSharp.Benchmarks/General/BasicMath/ClampFloat.cs
+++ b/tests/ImageSharp.Benchmarks/General/BasicMath/ClampFloat.cs
@@ -10,7 +10,7 @@ public class ClampFloat
{
private readonly float min = -1.5f;
private readonly float max = 2.5f;
- private static readonly float[] Values = { -10, -5, -3, -1.5f, -0.5f, 0f, 1f, 1.5f, 2.5f, 3, 10 };
+ private static readonly float[] Values = [-10, -5, -3, -1.5f, -0.5f, 0f, 1f, 1.5f, 2.5f, 3, 10];
[Benchmark(Baseline = true)]
public float UsingMathF()
diff --git a/tests/ImageSharp.Benchmarks/General/BasicMath/ClampSpan.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/ClampSpan.cs
index d47fcb687..b61ba27ff 100644
--- a/tests/ImageSharp.Benchmarks/General/BasicMath/ClampSpan.cs
+++ b/tests/ImageSharp.Benchmarks/General/BasicMath/ClampSpan.cs
@@ -12,7 +12,7 @@ public class ClampSpan
public void Setup()
{
- var r = new Random();
+ Random r = new();
for (int i = 0; i < A.Length; i++)
{
diff --git a/tests/ImageSharp.Benchmarks/General/BasicMath/ClampVector4.cs b/tests/ImageSharp.Benchmarks/General/BasicMath/ClampVector4.cs
index 186f88bb7..4969c3ef7 100644
--- a/tests/ImageSharp.Benchmarks/General/BasicMath/ClampVector4.cs
+++ b/tests/ImageSharp.Benchmarks/General/BasicMath/ClampVector4.cs
@@ -11,7 +11,7 @@ public class ClampVector4
{
private readonly float min = -1.5f;
private readonly float max = 2.5f;
- private static readonly float[] Values = { -10, -5, -3, -1.5f, -0.5f, 0f, 1f, 1.5f, 2.5f, 3, 10 };
+ private static readonly float[] Values = [-10, -5, -3, -1.5f, -0.5f, 0f, 1f, 1.5f, 2.5f, 3, 10];
[Benchmark(Baseline = true)]
public Vector4 UsingVectorClamp()
diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs
index a42c6c253..226dcc777 100644
--- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs
+++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_PackFromRgbPlanes.cs
@@ -209,7 +209,7 @@ public unsafe class PixelConversion_PackFromRgbPlanes
Vector256 vcontrol = SimdUtils.HwIntrinsics.PermuteMaskEvenOdd8x32().AsInt32();
- var va = Vector256.Create(1F);
+ Vector256 va = Vector256.Create(1F);
for (nuint i = 0; i < count; i++)
{
diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs
index f4fb9e420..232d8b3e2 100644
--- a/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs
+++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/PixelConversion_Rgba32_To_Bgra32.cs
@@ -252,8 +252,8 @@ public class PixelConversion_Rgba32_To_Bgra32
private static void BitopsSimdImpl(ref Octet s, ref Octet d)
{
Vector sVec = Unsafe.As, Vector>(ref s);
- var aMask = new Vector(0xFF00FF00);
- var bMask = new Vector(0x00FF00FF);
+ Vector aMask = new(0xFF00FF00);
+ Vector bMask = new(0x00FF00FF);
Vector aa = sVec & aMask;
Vector bb = sVec & bMask;
diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs
index 21bef5a15..8698f8223 100644
--- a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs
+++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestArgb.cs
@@ -103,6 +103,6 @@ public struct TestArgb : ITestPixel
vector = Numerics.Clamp(vector, Vector4.Zero, MaxBytes);
Vector128 result = Vector128.ConvertToInt32(vector.AsVector128()).AsByte();
- return new(result.GetElement(0), result.GetElement(4), result.GetElement(8), result.GetElement(12));
+ return new TestArgb(result.GetElement(0), result.GetElement(4), result.GetElement(8), result.GetElement(12));
}
}
diff --git a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs
index 1499fb7d3..751cd68b4 100644
--- a/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs
+++ b/tests/ImageSharp.Benchmarks/General/PixelConversion/TestRgba.cs
@@ -79,6 +79,6 @@ public struct TestRgba : ITestPixel
vector = Numerics.Clamp(vector, Vector4.Zero, MaxBytes);
Vector128 result = Vector128.ConvertToInt32(vector.AsVector128()).AsByte();
- return new(result.GetElement(0), result.GetElement(4), result.GetElement(8), result.GetElement(12));
+ return new TestRgba(result.GetElement(0), result.GetElement(4), result.GetElement(8), result.GetElement(12));
}
}
diff --git a/tests/ImageSharp.Benchmarks/General/Vector4Constants.cs b/tests/ImageSharp.Benchmarks/General/Vector4Constants.cs
index 2cd6a5a52..5919137bf 100644
--- a/tests/ImageSharp.Benchmarks/General/Vector4Constants.cs
+++ b/tests/ImageSharp.Benchmarks/General/Vector4Constants.cs
@@ -12,10 +12,10 @@ namespace SixLabors.ImageSharp.Benchmarks.General;
///
public class Vector4Constants
{
- private static readonly Vector4 A = new Vector4(1.2f);
- private static readonly Vector4 B = new Vector4(3.4f);
- private static readonly Vector4 C = new Vector4(5.6f);
- private static readonly Vector4 D = new Vector4(7.8f);
+ private static readonly Vector4 A = new(1.2f);
+ private static readonly Vector4 B = new(3.4f);
+ private static readonly Vector4 C = new(5.6f);
+ private static readonly Vector4 D = new(7.8f);
private Random random;
@@ -39,8 +39,8 @@ public class Vector4Constants
Vector4 x = (p * A / B) + (p * C / D);
Vector4 y = (p / A * B) + (p / C * D);
- var z = Vector4.Min(p, A);
- var w = Vector4.Max(p, B);
+ Vector4 z = Vector4.Min(p, A);
+ Vector4 w = Vector4.Max(p, B);
return x + y + z + w;
}
@@ -51,8 +51,8 @@ public class Vector4Constants
Vector4 x = (p * new Vector4(1.2f) / new Vector4(2.3f)) + (p * new Vector4(4.5f) / new Vector4(6.7f));
Vector4 y = (p / new Vector4(1.2f) * new Vector4(2.3f)) + (p / new Vector4(4.5f) * new Vector4(6.7f));
- var z = Vector4.Min(p, new Vector4(1.2f));
- var w = Vector4.Max(p, new Vector4(2.3f));
+ Vector4 z = Vector4.Min(p, new Vector4(1.2f));
+ Vector4 w = Vector4.Max(p, new Vector4(2.3f));
return x + y + z + w;
}
diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/BitwiseOrUint32.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/BitwiseOrUint32.cs
index 4d8d9b1ed..2f9b02b59 100644
--- a/tests/ImageSharp.Benchmarks/General/Vectorization/BitwiseOrUint32.cs
+++ b/tests/ImageSharp.Benchmarks/General/Vectorization/BitwiseOrUint32.cs
@@ -43,11 +43,11 @@ public class BitwiseOrUInt32
[Benchmark]
public void Simd()
{
- var v = new Vector(this.testValue);
+ Vector v = new(this.testValue);
for (int i = 0; i < this.input.Length; i += Vector.Count)
{
- var a = new Vector(this.input, i);
+ Vector a = new(this.input, i);
a = Vector.BitwiseOr(a, v);
a.CopyTo(this.result, i);
}
diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/DivFloat.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/DivFloat.cs
index 1b2c56ab9..fd243638b 100644
--- a/tests/ImageSharp.Benchmarks/General/Vectorization/DivFloat.cs
+++ b/tests/ImageSharp.Benchmarks/General/Vectorization/DivFloat.cs
@@ -43,11 +43,11 @@ public class DivFloat
[Benchmark]
public void Simd()
{
- var v = new Vector(this.testValue);
+ Vector v = new(this.testValue);
for (int i = 0; i < this.input.Length; i += Vector.Count)
{
- var a = new Vector(this.input, i);
+ Vector a = new(this.input, i);
a = a / v;
a.CopyTo(this.result, i);
}
diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/DivUInt32.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/DivUInt32.cs
index d102164e2..0d2923b61 100644
--- a/tests/ImageSharp.Benchmarks/General/Vectorization/DivUInt32.cs
+++ b/tests/ImageSharp.Benchmarks/General/Vectorization/DivUInt32.cs
@@ -44,11 +44,11 @@ public class DivUInt32
[Benchmark]
public void Simd()
{
- var v = new Vector(this.testValue);
+ Vector v = new(this.testValue);
for (int i = 0; i < this.input.Length; i += Vector.Count)
{
- var a = new Vector(this.input, i);
+ Vector a = new(this.input, i);
a = a / v;
a.CopyTo(this.result, i);
diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/Divide.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/Divide.cs
index 5277897bb..61ff9466e 100644
--- a/tests/ImageSharp.Benchmarks/General/Vectorization/Divide.cs
+++ b/tests/ImageSharp.Benchmarks/General/Vectorization/Divide.cs
@@ -57,7 +57,7 @@ public class DivInt16 : SIMDBenchmarkBase.Divide
{
protected override short GetTestValue() => 42;
- protected override Vector GetTestVector() => new Vector(new short[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 });
+ protected override Vector GetTestVector() => new(new short[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 });
[Benchmark(Baseline = true)]
public void Standard()
diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/MulFloat.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/MulFloat.cs
index a2eb8d417..801b0e161 100644
--- a/tests/ImageSharp.Benchmarks/General/Vectorization/MulFloat.cs
+++ b/tests/ImageSharp.Benchmarks/General/Vectorization/MulFloat.cs
@@ -43,11 +43,11 @@ public class MulFloat
[Benchmark]
public void SimdMultiplyByVector()
{
- var v = new Vector(this.testValue);
+ Vector v = new(this.testValue);
for (int i = 0; i < this.input.Length; i += Vector.Count)
{
- var a = new Vector(this.input, i);
+ Vector a = new(this.input, i);
a = a * v;
a.CopyTo(this.result, i);
}
@@ -60,7 +60,7 @@ public class MulFloat
for (int i = 0; i < this.input.Length; i += Vector.Count)
{
- var a = new Vector(this.input, i);
+ Vector a = new(this.input, i);
a = a * v;
a.CopyTo(this.result, i);
}
diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/MulUInt32.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/MulUInt32.cs
index a234970a5..db64486ad 100644
--- a/tests/ImageSharp.Benchmarks/General/Vectorization/MulUInt32.cs
+++ b/tests/ImageSharp.Benchmarks/General/Vectorization/MulUInt32.cs
@@ -43,11 +43,11 @@ public class MulUInt32
[Benchmark]
public void Simd()
{
- var v = new Vector(this.testValue);
+ Vector v = new(this.testValue);
for (int i = 0; i < this.input.Length; i += Vector.Count)
{
- var a = new Vector(this.input, i);
+ Vector a = new(this.input, i);
a = a * v;
a.CopyTo(this.result, i);
}
diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/Multiply.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/Multiply.cs
index 7e890cb92..d9542bc3f 100644
--- a/tests/ImageSharp.Benchmarks/General/Vectorization/Multiply.cs
+++ b/tests/ImageSharp.Benchmarks/General/Vectorization/Multiply.cs
@@ -40,7 +40,7 @@ public class MulInt16 : SIMDBenchmarkBase.Multiply
{
protected override short GetTestValue() => 42;
- protected override Vector GetTestVector() => new Vector(new short[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 });
+ protected override Vector GetTestVector() => new(new short[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17 });
[Benchmark(Baseline = true)]
public void Standard()
diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/Premultiply.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/Premultiply.cs
index 29b90accc..f99b141b4 100644
--- a/tests/ImageSharp.Benchmarks/General/Vectorization/Premultiply.cs
+++ b/tests/ImageSharp.Benchmarks/General/Vectorization/Premultiply.cs
@@ -12,14 +12,14 @@ public class Premultiply
[Benchmark(Baseline = true)]
public Vector4 PremultiplyByVal()
{
- var input = new Vector4(.5F);
+ Vector4 input = new(.5F);
return Vector4Utils.Premultiply(input);
}
[Benchmark]
public Vector4 PremultiplyByRef()
{
- var input = new Vector4(.5F);
+ Vector4 input = new(.5F);
Vector4Utils.PremultiplyRef(ref input);
return input;
}
@@ -27,7 +27,7 @@ public class Premultiply
[Benchmark]
public Vector4 PremultiplyRefWithPropertyAssign()
{
- var input = new Vector4(.5F);
+ Vector4 input = new(.5F);
Vector4Utils.PremultiplyRefWithPropertyAssign(ref input);
return input;
}
diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/ReinterpretUInt32AsFloat.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/ReinterpretUInt32AsFloat.cs
index 7d626d785..557d8ff38 100644
--- a/tests/ImageSharp.Benchmarks/General/Vectorization/ReinterpretUInt32AsFloat.cs
+++ b/tests/ImageSharp.Benchmarks/General/Vectorization/ReinterpretUInt32AsFloat.cs
@@ -53,8 +53,8 @@ public class ReinterpretUInt32AsFloat
{
for (int i = 0; i < this.input.Length; i += Vector.Count)
{
- var a = new Vector(this.input, i);
- var b = Vector.AsVectorSingle(a);
+ Vector a = new(this.input, i);
+ Vector b = Vector.AsVectorSingle(a);
b.CopyTo(this.result, i);
}
}
diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs
index 5f1f5666d..4048bc210 100644
--- a/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs
+++ b/tests/ImageSharp.Benchmarks/General/Vectorization/UInt32ToSingle.cs
@@ -27,20 +27,20 @@ public class UInt32ToSingle
nuint n = Count / (uint)Vector.Count;
- var bVec = new Vector(256.0f / 255.0f);
- var magicFloat = new Vector(32768.0f);
- var magicInt = new Vector(1191182336); // reinterpreted value of 32768.0f
- var mask = new Vector(255);
+ Vector bVec = new(256.0f / 255.0f);
+ Vector magicFloat = new(32768.0f);
+ Vector magicInt = new(1191182336); // reinterpreted value of 32768.0f
+ Vector mask = new(255);
for (nuint i = 0; i < n; i++)
{
ref Vector df = ref Unsafe.Add(ref b, i);
- var vi = Vector.AsVectorUInt32(df);
+ Vector vi = Vector.AsVectorUInt32(df);
vi &= mask;
vi |= magicInt;
- var vf = Vector.AsVectorSingle(vi);
+ Vector vf = Vector.AsVectorSingle(vi);
vf = (vf - magicFloat) * bVec;
df = vf;
@@ -55,7 +55,7 @@ public class UInt32ToSingle
ref Vector bf = ref Unsafe.As>(ref this.data[0]);
ref Vector bu = ref Unsafe.As, Vector>(ref bf);
- var scale = new Vector(1f / 255f);
+ Vector scale = new(1f / 255f);
for (nuint i = 0; i < n; i++)
{
@@ -74,7 +74,7 @@ public class UInt32ToSingle
ref Vector bf = ref Unsafe.As>(ref this.data[0]);
ref Vector bu = ref Unsafe.As, Vector>(ref bf);
- var scale = new Vector(1f / 255f);
+ Vector scale = new(1f / 255f);
for (nuint i = 0; i < n; i++)
{
@@ -91,7 +91,7 @@ public class UInt32ToSingle
nuint n = Count / (uint)Vector.Count;
ref Vector bf = ref Unsafe.As>(ref this.data[0]);
- var scale = new Vector(1f / 255f);
+ Vector scale = new(1f / 255f);
for (nuint i = 0; i < n; i++)
{
diff --git a/tests/ImageSharp.Benchmarks/General/Vectorization/VectorFetching.cs b/tests/ImageSharp.Benchmarks/General/Vectorization/VectorFetching.cs
index 5d20f29d1..9c7fd5b6c 100644
--- a/tests/ImageSharp.Benchmarks/General/Vectorization/VectorFetching.cs
+++ b/tests/ImageSharp.Benchmarks/General/Vectorization/VectorFetching.cs
@@ -47,11 +47,11 @@ public class VectorFetching
[Benchmark]
public void FetchWithVectorConstructor()
{
- var v = new Vector(this.testValue);
+ Vector v = new(this.testValue);
for (int i = 0; i < this.data.Length; i += Vector.Count)
{
- var a = new Vector(this.data, i);
+ Vector a = new(this.data, i);
a = a * v;
a.CopyTo(this.data, i);
}
@@ -60,7 +60,7 @@ public class VectorFetching
[Benchmark]
public void FetchWithUnsafeCast()
{
- var v = new Vector(this.testValue);
+ Vector v = new(this.testValue);
ref Vector start = ref Unsafe.As>(ref this.data[0]);
nuint n = (uint)this.InputSize / (uint)Vector.Count;
@@ -79,7 +79,7 @@ public class VectorFetching
[Benchmark]
public void FetchWithUnsafeCastNoTempVector()
{
- var v = new Vector(this.testValue);
+ Vector v = new(this.testValue);
ref Vector start = ref Unsafe.As>(ref this.data[0]);
nuint n = (uint)this.InputSize / (uint)Vector.Count;
@@ -94,9 +94,9 @@ public class VectorFetching
[Benchmark]
public void FetchWithUnsafeCastFromReference()
{
- var v = new Vector(this.testValue);
+ Vector v = new(this.testValue);
- var span = new Span(this.data);
+ Span span = new(this.data);
ref Vector start = ref Unsafe.As>(ref MemoryMarshal.GetReference(span));
diff --git a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj
index c92bb6a6b..fa5fdd816 100644
--- a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj
+++ b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj
@@ -19,7 +19,7 @@
BenchmarkDotNet requires a certain structure to the code,
as such, some of these rules cannot be implemented.
-->
-
+
@@ -39,7 +39,7 @@
- net8.0;net9.0
+ net8.0;net10.0
@@ -57,8 +57,9 @@
-
-
+
+
+
diff --git a/tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressBenchmarks.cs b/tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressBenchmarks.cs
index 04621695c..0731c7c00 100644
--- a/tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressBenchmarks.cs
+++ b/tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressBenchmarks.cs
@@ -18,7 +18,7 @@ public class LoadResizeSaveStressBenchmarks
[GlobalSetup]
public void Setup()
{
- this.runner = new LoadResizeSaveStressRunner()
+ this.runner = new LoadResizeSaveStressRunner
{
ImageCount = Environment.ProcessorCount,
Filter = Filter
@@ -34,12 +34,12 @@ public class LoadResizeSaveStressBenchmarks
}
public int[] ParallelismValues { get; } =
- {
+ [
// Environment.ProcessorCount,
// Environment.ProcessorCount / 2,
// Environment.ProcessorCount / 4,
1
- };
+ ];
[Benchmark]
[ArgumentsSource(nameof(ParallelismValues))]
diff --git a/tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressRunner.cs b/tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressRunner.cs
index 44c248dc9..f8bf19d57 100644
--- a/tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressRunner.cs
+++ b/tests/ImageSharp.Benchmarks/LoadResizeSave/LoadResizeSaveStressRunner.cs
@@ -53,7 +53,7 @@ public class LoadResizeSaveStressRunner
public int ThumbnailSize { get; set; } = 150;
private static readonly string[] ProgressiveFiles =
- {
+ [
"ancyloscelis-apiformis-m-paraguay-face_2014-08-08-095255-zs-pmax_15046500892_o.jpg",
"acanthopus-excellens-f-face-brasil_2014-08-06-132105-zs-pmax_14792513890_o.jpg",
"bee-ceratina-monster-f-ukraine-face_2014-08-09-123342-zs-pmax_15068816101_o.jpg",
@@ -84,8 +84,8 @@ public class LoadResizeSaveStressRunner
"triepeolus-simplex-m-face-md-kent-county_2014-07-22-100937-zs-pmax_14805405233_o.jpg",
"washed-megachile-f-face-chile_2014-08-06-103414-zs-pmax_14977843152_o.jpg",
"xylocopa-balck-violetwing-f-kyrgystan-angle_2014-08-09-182433-zs-pmax_15123416061_o.jpg",
- "xylocopa-india-yellow-m-india-face_2014-08-10-111701-zs-pmax_15166559172_o.jpg",
- };
+ "xylocopa-india-yellow-m-india-face_2014-08-10-111701-zs-pmax_15166559172_o.jpg"
+ ];
public void Init()
{
@@ -148,7 +148,7 @@ public class LoadResizeSaveStressRunner
private void LogImageProcessed(int width, int height)
{
- this.LastProcessedImageSize = new Size(width, height);
+ this.LastProcessedImageSize = new ImageSharpSize(width, height);
double pixels = width * (double)height;
this.TotalProcessedMegapixels += pixels / 1_000_000.0;
}
diff --git a/tests/ImageSharp.Benchmarks/Processing/HistogramEqualization.cs b/tests/ImageSharp.Benchmarks/Processing/HistogramEqualization.cs
index 135145a31..93ac9fc0e 100644
--- a/tests/ImageSharp.Benchmarks/Processing/HistogramEqualization.cs
+++ b/tests/ImageSharp.Benchmarks/Processing/HistogramEqualization.cs
@@ -33,7 +33,7 @@ public class HistogramEqualization
[Benchmark(Description = "Global Histogram Equalization")]
public void GlobalHistogramEqualization()
=> this.image.Mutate(img => img.HistogramEqualization(
- new HistogramEqualizationOptions()
+ new HistogramEqualizationOptions
{
LuminanceLevels = 256,
Method = HistogramEqualizationMethod.Global
@@ -42,7 +42,7 @@ public class HistogramEqualization
[Benchmark(Description = "AdaptiveHistogramEqualization (Tile interpolation)")]
public void AdaptiveHistogramEqualization()
=> this.image.Mutate(img => img.HistogramEqualization(
- new HistogramEqualizationOptions()
+ new HistogramEqualizationOptions
{
LuminanceLevels = 256,
Method = HistogramEqualizationMethod.AdaptiveTileInterpolation
diff --git a/tests/ImageSharp.Benchmarks/Processing/OilPaint.cs b/tests/ImageSharp.Benchmarks/Processing/OilPaint.cs
index e3e413fe4..707748499 100644
--- a/tests/ImageSharp.Benchmarks/Processing/OilPaint.cs
+++ b/tests/ImageSharp.Benchmarks/Processing/OilPaint.cs
@@ -13,7 +13,7 @@ public class OilPaint
[Benchmark]
public void DoOilPaint()
{
- using Image image = new Image(1920, 1200, new(127, 191, 255));
+ using Image image = new(1920, 1200, new RgbaVector(127, 191, 255));
image.Mutate(ctx => ctx.OilPaint());
}
}
diff --git a/tests/ImageSharp.Benchmarks/Processing/Resize.cs b/tests/ImageSharp.Benchmarks/Processing/Resize.cs
index 09673cb96..3cc10afb7 100644
--- a/tests/ImageSharp.Benchmarks/Processing/Resize.cs
+++ b/tests/ImageSharp.Benchmarks/Processing/Resize.cs
@@ -12,7 +12,7 @@ using SDImage = System.Drawing.Image;
namespace SixLabors.ImageSharp.Benchmarks;
-[Config(typeof(Config.Standard))]
+[Config(typeof(Config.StandardInProcess))]
public abstract class Resize
where TPixel : unmanaged, IPixel
{
@@ -22,7 +22,7 @@ public abstract class Resize
private SDImage sourceBitmap;
- protected Configuration Configuration { get; } = new Configuration(new JpegConfigurationModule());
+ protected Configuration Configuration { get; } = new(new JpegConfigurationModule());
protected int DestSize { get; private set; }
diff --git a/tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj b/tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj
index 832f3d171..bc52610d2 100644
--- a/tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj
+++ b/tests/ImageSharp.Tests.ProfilingSandbox/ImageSharp.Tests.ProfilingSandbox.csproj
@@ -19,7 +19,7 @@
- net8.0;net9.0
+ net8.0;net10.0
diff --git a/tests/ImageSharp.Tests.ProfilingSandbox/LoadResizeSaveParallelMemoryStress.cs b/tests/ImageSharp.Tests.ProfilingSandbox/LoadResizeSaveParallelMemoryStress.cs
index 248912b14..6850756df 100644
--- a/tests/ImageSharp.Tests.ProfilingSandbox/LoadResizeSaveParallelMemoryStress.cs
+++ b/tests/ImageSharp.Tests.ProfilingSandbox/LoadResizeSaveParallelMemoryStress.cs
@@ -17,7 +17,7 @@ internal class LoadResizeSaveParallelMemoryStress
{
private LoadResizeSaveParallelMemoryStress()
{
- this.Benchmarks = new LoadResizeSaveStressRunner()
+ this.Benchmarks = new LoadResizeSaveStressRunner
{
Filter = JpegKind.Baseline,
};
@@ -38,7 +38,7 @@ internal class LoadResizeSaveParallelMemoryStress
Console.WriteLine($"64 bit: {Environment.Is64BitProcess}");
CommandLineOptions options = args.Length > 0 ? CommandLineOptions.Parse(args) : null;
- var lrs = new LoadResizeSaveParallelMemoryStress();
+ LoadResizeSaveParallelMemoryStress lrs = new();
if (options != null)
{
lrs.Benchmarks.MaxDegreeOfParallelism = options.MaxDegreeOfParallelism;
@@ -108,7 +108,7 @@ internal class LoadResizeSaveParallelMemoryStress
}
}
- var stats = new Stats(timer, lrs.Benchmarks.TotalProcessedMegapixels);
+ Stats stats = new(timer, lrs.Benchmarks.TotalProcessedMegapixels);
Console.WriteLine($"Total Megapixels: {stats.TotalMegapixels}, TotalOomRetries: {UnmanagedMemoryHandle.TotalOomRetries}, TotalOutstandingHandles: {UnmanagedMemoryHandle.TotalOutstandingHandles}, Total Gen2 GC count: {GC.CollectionCount(2)}");
Console.WriteLine(stats.GetMarkdown());
if (options?.FileOutput != null)
@@ -203,7 +203,7 @@ internal class LoadResizeSaveParallelMemoryStress
public string GetMarkdown()
{
- var bld = new StringBuilder();
+ StringBuilder bld = new();
bld.AppendLine($"| {nameof(this.TotalSeconds)} | {nameof(this.MegapixelsPerSec)} | {nameof(this.MegapixelsPerSecPerCpu)} |");
bld.AppendLine(
$"| {L(nameof(this.TotalSeconds))} | {L(nameof(this.MegapixelsPerSec))} | {L(nameof(this.MegapixelsPerSecPerCpu))} |");
diff --git a/tests/ImageSharp.Tests.ProfilingSandbox/Program.cs b/tests/ImageSharp.Tests.ProfilingSandbox/Program.cs
index b5c8b70cd..8ba862560 100644
--- a/tests/ImageSharp.Tests.ProfilingSandbox/Program.cs
+++ b/tests/ImageSharp.Tests.ProfilingSandbox/Program.cs
@@ -52,7 +52,7 @@ public class Program
{
Assembly assembly = typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly;
Console.WriteLine(assembly.Location);
- string[] assemblyPath = assembly.Location.Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
+ string[] assemblyPath = assembly.Location.Split(['/', '\\'], StringSplitOptions.RemoveEmptyEntries);
int netCoreAppIndex = Array.IndexOf(assemblyPath, "Microsoft.NETCore.App");
if (netCoreAppIndex > 0 && netCoreAppIndex < assemblyPath.Length - 2)
{
@@ -64,13 +64,13 @@ public class Program
private static void RunResizeProfilingTest()
{
- var test = new ResizeProfilingBenchmarks(new ConsoleOutput());
+ ResizeProfilingBenchmarks test = new(new ConsoleOutput());
test.ResizeBicubic(4000, 4000);
}
private static void RunToVector4ProfilingTest()
{
- var tests = new PixelOperationsTests.Rgba32_OperationsTests(new ConsoleOutput());
+ PixelOperationsTests.Rgba32_OperationsTests tests = new(new ConsoleOutput());
tests.Benchmark_ToVector4();
}
}
diff --git a/tests/ImageSharp.Tests/Color/ColorTests.CastTo.cs b/tests/ImageSharp.Tests/Color/ColorTests.CastTo.cs
index 4247345c7..2e2f0d07d 100644
--- a/tests/ImageSharp.Tests/Color/ColorTests.CastTo.cs
+++ b/tests/ImageSharp.Tests/Color/ColorTests.CastTo.cs
@@ -13,10 +13,10 @@ public partial class ColorTests
[Fact]
public void Rgba64()
{
- var source = new Rgba64(100, 2222, 3333, 4444);
+ Rgba64 source = new(100, 2222, 3333, 4444);
// Act:
- var color = Color.FromPixel(source);
+ Color color = Color.FromPixel(source);
// Assert:
Rgba64 data = color.ToPixel();
@@ -26,10 +26,10 @@ public partial class ColorTests
[Fact]
public void Rgba32()
{
- var source = new Rgba32(1, 22, 33, 231);
+ Rgba32 source = new(1, 22, 33, 231);
// Act:
- var color = Color.FromPixel(source);
+ Color color = Color.FromPixel(source);
// Assert:
Rgba32 data = color.ToPixel();
@@ -39,10 +39,10 @@ public partial class ColorTests
[Fact]
public void Argb32()
{
- var source = new Argb32(1, 22, 33, 231);
+ Argb32 source = new(1, 22, 33, 231);
// Act:
- var color = Color.FromPixel(source);
+ Color color = Color.FromPixel(source);
// Assert:
Argb32 data = color.ToPixel();
@@ -52,10 +52,10 @@ public partial class ColorTests
[Fact]
public void Bgra32()
{
- var source = new Bgra32(1, 22, 33, 231);
+ Bgra32 source = new(1, 22, 33, 231);
// Act:
- var color = Color.FromPixel(source);
+ Color color = Color.FromPixel(source);
// Assert:
Bgra32 data = color.ToPixel();
@@ -65,10 +65,10 @@ public partial class ColorTests
[Fact]
public void Abgr32()
{
- var source = new Abgr32(1, 22, 33, 231);
+ Abgr32 source = new(1, 22, 33, 231);
// Act:
- var color = Color.FromPixel(source);
+ Color color = Color.FromPixel(source);
// Assert:
Abgr32 data = color.ToPixel();
@@ -78,10 +78,10 @@ public partial class ColorTests
[Fact]
public void Rgb24()
{
- var source = new Rgb24(1, 22, 231);
+ Rgb24 source = new(1, 22, 231);
// Act:
- var color = Color.FromPixel(source);
+ Color color = Color.FromPixel(source);
// Assert:
Rgb24 data = color.ToPixel();
@@ -91,10 +91,10 @@ public partial class ColorTests
[Fact]
public void Bgr24()
{
- var source = new Bgr24(1, 22, 231);
+ Bgr24 source = new(1, 22, 231);
// Act:
- var color = Color.FromPixel(source);
+ Color color = Color.FromPixel(source);
// Assert:
Bgr24 data = color.ToPixel();
@@ -129,7 +129,7 @@ public partial class ColorTests
where TPixel : unmanaged, IPixel
{
// Act:
- var color = Color.FromPixel(source);
+ Color color = Color.FromPixel(source);
// Assert:
TPixel actual = color.ToPixel();
@@ -150,7 +150,7 @@ public partial class ColorTests
where TPixel2 : unmanaged, IPixel
{
// Act:
- var color = Color.FromPixel(source);
+ Color color = Color.FromPixel(source);
// Assert:
TPixel2 actual = color.ToPixel();
diff --git a/tests/ImageSharp.Tests/Color/ColorTests.cs b/tests/ImageSharp.Tests/Color/ColorTests.cs
index d430df5b4..c482fc998 100644
--- a/tests/ImageSharp.Tests/Color/ColorTests.cs
+++ b/tests/ImageSharp.Tests/Color/ColorTests.cs
@@ -67,9 +67,9 @@ public partial class ColorTests
[Theory]
[InlineData(false)]
[InlineData(true)]
- public void ToHex(bool highPrecision)
+ public void ToHexRgba(bool highPrecision)
{
- string expected = "ABCD1234";
+ const string expected = "AABBCCDD";
Color color = Color.ParseHex(expected);
if (highPrecision)
@@ -81,10 +81,27 @@ public partial class ColorTests
Assert.Equal(expected, actual);
}
+ [Theory]
+ [InlineData(false)]
+ [InlineData(true)]
+ public void ToHexArgb(bool highPrecision)
+ {
+ const string expected = "AABBCCDD";
+ Color color = Color.ParseHex(expected, ColorHexFormat.Argb);
+
+ if (highPrecision)
+ {
+ color = Color.FromPixel(color.ToPixel());
+ }
+
+ string actual = color.ToHex(ColorHexFormat.Argb);
+ Assert.Equal(expected, actual);
+ }
+
[Fact]
public void WebSafePalette_IsCorrect()
{
- Rgba32[] actualPalette = Color.WebSafePalette.ToArray().Select(c => c.ToPixel()).ToArray();
+ Rgba32[] actualPalette = [.. Color.WebSafePalette.ToArray().Select(c => c.ToPixel())];
for (int i = 0; i < ReferencePalette.WebSafeColors.Length; i++)
{
@@ -95,7 +112,7 @@ public partial class ColorTests
[Fact]
public void WernerPalette_IsCorrect()
{
- Rgba32[] actualPalette = Color.WernerPalette.ToArray().Select(c => c.ToPixel()).ToArray();
+ Rgba32[] actualPalette = [.. Color.WernerPalette.ToArray().Select(c => c.ToPixel())];
for (int i = 0; i < ReferencePalette.WernerColors.Length; i++)
{
@@ -103,7 +120,7 @@ public partial class ColorTests
}
}
- public class FromHex
+ public class FromHexRgba
{
[Fact]
public void ShortHex()
@@ -126,6 +143,23 @@ public partial class ColorTests
Assert.Equal(new Rgba32(0, 0, 0, 255), actual.ToPixel());
}
+ [Fact]
+ public void LongHex()
+ {
+ Assert.Equal(new Rgba32(255, 255, 255, 0), Color.ParseHex("#FFFFFF00").ToPixel());
+ Assert.Equal(new Rgba32(255, 255, 255, 128), Color.ParseHex("#FFFFFF80").ToPixel());
+ }
+
+ [Fact]
+ public void TryLongHex()
+ {
+ Assert.True(Color.TryParseHex("#FFFFFF00", out Color actual));
+ Assert.Equal(new Rgba32(255, 255, 255, 0), actual.ToPixel());
+
+ Assert.True(Color.TryParseHex("#FFFFFF80", out actual));
+ Assert.Equal(new Rgba32(255, 255, 255, 128), actual.ToPixel());
+ }
+
[Fact]
public void LeadingPoundIsOptional()
{
@@ -152,6 +186,72 @@ public partial class ColorTests
public void FalseOnNull() => Assert.False(Color.TryParseHex(null, out Color _));
}
+ public class FromHexArgb
+ {
+ [Fact]
+ public void ShortHex()
+ {
+ Assert.Equal(new Rgb24(255, 255, 255), Color.ParseHex("#fff", ColorHexFormat.Argb).ToPixel());
+ Assert.Equal(new Rgb24(255, 255, 255), Color.ParseHex("fff", ColorHexFormat.Argb).ToPixel());
+ Assert.Equal(new Argb32(0, 0, 255, 0), Color.ParseHex("000f", ColorHexFormat.Argb).ToPixel());
+ }
+
+ [Fact]
+ public void TryShortHex()
+ {
+ Assert.True(Color.TryParseHex("#fff", out Color actual, ColorHexFormat.Argb));
+ Assert.Equal(new Rgb24(255, 255, 255), actual.ToPixel());
+
+ Assert.True(Color.TryParseHex("fff", out actual, ColorHexFormat.Argb));
+ Assert.Equal(new Rgb24(255, 255, 255), actual.ToPixel());
+
+ Assert.True(Color.TryParseHex("000f", out actual, ColorHexFormat.Argb));
+ Assert.Equal(new Argb32(0, 0, 255, 0), actual.ToPixel());
+ }
+
+ [Fact]
+ public void LongHex()
+ {
+ Assert.Equal(new Argb32(255, 255, 255, 0), Color.ParseHex("#00FFFFFF", ColorHexFormat.Argb).ToPixel());
+ Assert.Equal(new Argb32(255, 255, 255, 128), Color.ParseHex("#80FFFFFF", ColorHexFormat.Argb).ToPixel());
+ }
+
+ [Fact]
+ public void TryLongHex()
+ {
+ Assert.True(Color.TryParseHex("#00FFFFFF", out Color actual, ColorHexFormat.Argb));
+ Assert.Equal(new Argb32(255, 255, 255, 0), actual.ToPixel());
+
+ Assert.True(Color.TryParseHex("#80FFFFFF", out actual, ColorHexFormat.Argb));
+ Assert.Equal(new Argb32(255, 255, 255, 128), actual.ToPixel());
+ }
+
+ [Fact]
+ public void LeadingPoundIsOptional()
+ {
+ Assert.Equal(new Rgb24(0, 128, 128), Color.ParseHex("#008080", ColorHexFormat.Argb).ToPixel());
+ Assert.Equal(new Rgb24(0, 128, 128), Color.ParseHex("008080", ColorHexFormat.Argb).ToPixel());
+ }
+
+ [Fact]
+ public void ThrowsOnEmpty() => Assert.Throws(() => Color.ParseHex(string.Empty, ColorHexFormat.Argb));
+
+ [Fact]
+ public void ThrowsOnInvalid() => Assert.Throws(() => Color.ParseHex("!", ColorHexFormat.Argb));
+
+ [Fact]
+ public void ThrowsOnNull() => Assert.Throws(() => Color.ParseHex(null, ColorHexFormat.Argb));
+
+ [Fact]
+ public void FalseOnEmpty() => Assert.False(Color.TryParseHex(string.Empty, out Color _, ColorHexFormat.Argb));
+
+ [Fact]
+ public void FalseOnInvalid() => Assert.False(Color.TryParseHex("!", out Color _, ColorHexFormat.Argb));
+
+ [Fact]
+ public void FalseOnNull() => Assert.False(Color.TryParseHex(null, out Color _, ColorHexFormat.Argb));
+ }
+
public class FromString
{
[Fact]
diff --git a/tests/ImageSharp.Tests/Color/ReferencePalette.cs b/tests/ImageSharp.Tests/Color/ReferencePalette.cs
index 8e2696109..88787afd4 100644
--- a/tests/ImageSharp.Tests/Color/ReferencePalette.cs
+++ b/tests/ImageSharp.Tests/Color/ReferencePalette.cs
@@ -9,7 +9,7 @@ internal static class ReferencePalette
/// Gets a collection of named, web safe, colors as defined in the CSS Color Module Level 4.
///
public static readonly Color[] WebSafeColors =
- {
+ [
Color.AliceBlue,
Color.AntiqueWhite,
Color.Aqua,
@@ -152,14 +152,14 @@ internal static class ReferencePalette
Color.WhiteSmoke,
Color.Yellow,
Color.YellowGreen
- };
+ ];
///
/// Gets a collection of colors as defined in the original second edition of Werner’s Nomenclature of Colours 1821.
/// The hex codes were collected and defined by Nicholas Rougeux
///
public static readonly Color[] WernerColors =
- {
+ [
Color.ParseHex("#f1e9cd"),
Color.ParseHex("#f2e7cf"),
Color.ParseHex("#ece6d0"),
@@ -270,10 +270,10 @@ internal static class ReferencePalette
Color.ParseHex("#9b856b"),
Color.ParseHex("#766051"),
Color.ParseHex("#453b32")
- };
+ ];
public static readonly Dictionary ColorNames =
- new Dictionary(StringComparer.OrdinalIgnoreCase)
+ new(StringComparer.OrdinalIgnoreCase)
{
{ nameof(Color.AliceBlue), Color.AliceBlue },
{ nameof(Color.AntiqueWhite), Color.AntiqueWhite },
diff --git a/tests/ImageSharp.Tests/Color/RgbaDouble.cs b/tests/ImageSharp.Tests/Color/RgbaDouble.cs
index 9a751e879..76fdf365c 100644
--- a/tests/ImageSharp.Tests/Color/RgbaDouble.cs
+++ b/tests/ImageSharp.Tests/Color/RgbaDouble.cs
@@ -115,7 +115,7 @@ public struct RgbaDouble : IPixel
public static RgbaDouble FromVector4(Vector4 source)
{
source = Numerics.Clamp(source, Vector4.Zero, Vector4.One);
- return new(source.X, source.Y, source.Z, source.W);
+ return new RgbaDouble(source.X, source.Y, source.Z, source.W);
}
///
diff --git a/tests/ImageSharp.Tests/ColorProfiles/ApproximateColorProfileComparer.cs b/tests/ImageSharp.Tests/ColorProfiles/ApproximateColorProfileComparer.cs
index 56d495a87..f4078887c 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/ApproximateColorProfileComparer.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/ApproximateColorProfileComparer.cs
@@ -22,7 +22,9 @@ internal readonly struct ApproximateColorProfileComparer :
IEqualityComparer,
IEqualityComparer,
IEqualityComparer,
- IEqualityComparer
+ IEqualityComparer,
+ IEqualityComparer,
+ IEqualityComparer
{
private readonly float epsilon;
@@ -58,6 +60,10 @@ internal readonly struct ApproximateColorProfileComparer :
public bool Equals(HunterLab x, HunterLab y) => this.Equals(x.L, y.L) && this.Equals(x.A, y.A) && this.Equals(x.B, y.B);
+ public bool Equals(Y x, Y y) => this.Equals(x.L, y.L);
+
+ public bool Equals(YccK x, YccK y) => this.Equals(x.Y, y.Y) && this.Equals(x.Cb, y.Cb) && this.Equals(x.Cr, y.Cr) && this.Equals(x.K, y.K);
+
public int GetHashCode([DisallowNull] CieLab obj) => obj.GetHashCode();
public int GetHashCode([DisallowNull] CieXyz obj) => obj.GetHashCode();
@@ -84,6 +90,10 @@ internal readonly struct ApproximateColorProfileComparer :
public int GetHashCode([DisallowNull] HunterLab obj) => obj.GetHashCode();
+ public int GetHashCode([DisallowNull] Y obj) => obj.GetHashCode();
+
+ public int GetHashCode([DisallowNull] YccK obj) => obj.GetHashCode();
+
private bool Equals(float x, float y)
{
float d = x - y;
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLabAndCieLchConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLabAndCieLchConversionTests.cs
index 9a894c776..d6e373895 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLabAndCieLchConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLabAndCieLchConversionTests.cs
@@ -12,6 +12,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
/// Test data generated using:
///
///
+[Trait("Color", "Conversion")]
public class CieLabAndCieLchConversionTests
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0001f);
@@ -30,7 +31,7 @@ public class CieLabAndCieLchConversionTests
// Arrange
CieLch input = new(l, c, h);
CieLab expected = new(l2, a, b);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D50 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D50 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLch[5];
@@ -65,7 +66,7 @@ public class CieLabAndCieLchConversionTests
// Arrange
CieLab input = new(l, a, b);
CieLch expected = new(l2, c, h);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D50 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D50 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLab[5];
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLabAndCieLchuvConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLabAndCieLchuvConversionTests.cs
index 4b1b5e1a5..73fa7128f 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLabAndCieLchuvConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLabAndCieLchuvConversionTests.cs
@@ -24,7 +24,7 @@ public class CieLabAndCieLchuvConversionTests
// Arrange
CieLchuv input = new(l, c, h);
CieLab expected = new(l2, a, b);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D50 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D50 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLchuv[5];
@@ -53,7 +53,7 @@ public class CieLabAndCieLchuvConversionTests
// Arrange
CieLab input = new(l, a, b);
CieLchuv expected = new(l2, c, h);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLab[5];
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLabAndCieLuvConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLabAndCieLuvConversionTests.cs
index 44756c779..0846bdda3 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLabAndCieLuvConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLabAndCieLuvConversionTests.cs
@@ -24,7 +24,7 @@ public class CieLabAndCieLuvConversionTests
// Arrange
CieLuv input = new(l, u, v);
CieLab expected = new(l2, a, b);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D50 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D50 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLuv[5];
@@ -53,7 +53,7 @@ public class CieLabAndCieLuvConversionTests
// Arrange
CieLab input = new(l, a, b);
CieLuv expected = new(l2, u, v);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLab[5];
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLabAndYCbCrConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLabAndYCbCrConversionTests.cs
index 9a29b1539..15677c46f 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLabAndYCbCrConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLabAndYCbCrConversionTests.cs
@@ -13,8 +13,9 @@ public class CieLabAndYCbCrConversionTests
private static readonly ApproximateColorProfileComparer Comparer = new(.0002F);
[Theory]
- [InlineData(0, 128, 128, 0, 0, 0)]
- [InlineData(87.4179, 133.9763, 247.5308, 55.06287, 82.54838, 23.1697)]
+ [InlineData(1, .5F, .5F, 100, 0, 0)]
+ [InlineData(0, .5F, .5F, 0, 0, 0)]
+ [InlineData(.5F, .5F, .5F, 53.38897F, 0, 0)]
public void Convert_YCbCr_to_CieLab(float y, float cb, float cr, float l, float a, float b)
{
// Arrange
@@ -41,8 +42,9 @@ public class CieLabAndYCbCrConversionTests
}
[Theory]
- [InlineData(0, 0, 0, 0, 128, 128)]
- [InlineData(55.06287, 82.54838, 23.1697, 87.41701, 133.97232, 247.5314)]
+ [InlineData(100, 0, 0, 1, .5F, .5F)]
+ [InlineData(0, 0, 0, 0, .5F, .5F)]
+ [InlineData(53.38897F, 0, 0, .5F, .5F, .5F)]
public void Convert_CieLab_to_YCbCr(float l, float a, float b, float y, float cb, float cr)
{
// Arrange
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLabTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLabTests.cs
index 3c015259b..69fabc750 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLabTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLabTests.cs
@@ -9,6 +9,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
///
/// Tests the struct.
///
+[Trait("Color", "Conversion")]
public class CieLabTests
{
[Fact]
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLchAndCieLuvConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLchAndCieLuvConversionTests.cs
index 598d4af33..12313281f 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLchAndCieLuvConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLchAndCieLuvConversionTests.cs
@@ -20,7 +20,7 @@ public class CieLchAndCieLuvConversionTests
// Arrange
CieLch input = new(l, c, h);
CieLuv expected = new(l2, u, v);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLch[5];
@@ -48,7 +48,7 @@ public class CieLchAndCieLuvConversionTests
// Arrange
CieLuv input = new(l2, u, v);
CieLch expected = new(l, c, h);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D50 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D50 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLuv[5];
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLchuvAndCieLchConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLchuvAndCieLchConversionTests.cs
index a3e0b45e0..857bdb3da 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLchuvAndCieLchConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLchuvAndCieLchConversionTests.cs
@@ -20,7 +20,7 @@ public class CieLchuvAndCieLchConversionTests
// Arrange
CieLch input = new(l2, c2, h2);
CieLchuv expected = new(l, c, h);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLch[5];
@@ -48,7 +48,7 @@ public class CieLchuvAndCieLchConversionTests
// Arrange
CieLchuv input = new(l, c, h);
CieLch expected = new(l2, c2, h2);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D50 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D50 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLchuv[5];
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLchuvAndCieLuvConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLchuvAndCieLuvConversionTests.cs
index 465237490..424cb8cc7 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLchuvAndCieLuvConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLchuvAndCieLuvConversionTests.cs
@@ -12,6 +12,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
/// Test data generated using:
///
///
+[Trait("Color", "Conversion")]
public class CieLchuvAndCieLuvConversionTests
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0001F);
@@ -30,7 +31,7 @@ public class CieLchuvAndCieLuvConversionTests
// Arrange
CieLchuv input = new(l, c, h);
CieLuv expected = new(l2, u, v);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLchuv[5];
@@ -66,7 +67,7 @@ public class CieLchuvAndCieLuvConversionTests
// Arrange
CieLuv input = new(l, u, v);
CieLchuv expected = new(l2, c, h);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLuv[5];
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLchuvAndCmykConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLchuvAndCmykConversionTests.cs
index 60ac3da16..3c8a93ee1 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLchuvAndCmykConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLchuvAndCmykConversionTests.cs
@@ -20,7 +20,7 @@ public class CieLchuvAndCmykConversionTests
// Arrange
Cmyk input = new(c2, m, y, k);
CieLchuv expected = new(l, c, h);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new Cmyk[5];
@@ -49,7 +49,7 @@ public class CieLchuvAndCmykConversionTests
// Arrange
CieLchuv input = new(l, c, h);
Cmyk expected = new(c2, m, y, k);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLchuv[5];
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLchuvTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLchuvTests.cs
index 0b737cdfc..3fe550a5b 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLchuvTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLchuvTests.cs
@@ -9,6 +9,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
///
/// Tests the struct.
///
+[Trait("Color", "Conversion")]
public class CieLchuvTests
{
[Fact]
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndCieXyyConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndCieXyyConversionTests.cs
index e73edcda7..08e73a1a7 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndCieXyyConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndCieXyyConversionTests.cs
@@ -20,7 +20,7 @@ public class CieLuvAndCieXyyConversionTests
// Arrange
CieLuv input = new(l, u, v);
CieXyy expected = new(x, y, yl);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLuv[5];
@@ -49,7 +49,7 @@ public class CieLuvAndCieXyyConversionTests
// Arrange
CieXyy input = new(x, y, yl);
CieLuv expected = new(l, u, v);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieXyy[5];
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndHslConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndHslConversionTests.cs
index b178b22b2..bfcd236c7 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndHslConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndHslConversionTests.cs
@@ -20,7 +20,7 @@ public class CieLuvAndHslConversionTests
// Arrange
CieLuv input = new(l, u, v);
Hsl expected = new(h, s, l2);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLuv[5];
@@ -49,7 +49,7 @@ public class CieLuvAndHslConversionTests
// Arrange
Hsl input = new(h, s, l2);
CieLuv expected = new(l, u, v);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new Hsl[5];
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndHsvConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndHsvConversionTests.cs
index 286609337..8a25f95b7 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndHsvConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndHsvConversionTests.cs
@@ -20,7 +20,7 @@ public class CieLuvAndHsvConversionTests
// Arrange
CieLuv input = new(l, u, v);
Hsv expected = new(h, s, v2);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLuv[5];
@@ -49,7 +49,7 @@ public class CieLuvAndHsvConversionTests
// Arrange
Hsv input = new(h, s, v2);
CieLuv expected = new(l, u, v);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new Hsv[5];
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndHunterLabConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndHunterLabConversionTests.cs
index 73b605fb6..1c667f679 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndHunterLabConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndHunterLabConversionTests.cs
@@ -20,7 +20,7 @@ public class CieLuvAndHunterLabConversionTests
// Arrange
CieLuv input = new(l, u, v);
HunterLab expected = new(l2, a, b);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D50 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D50 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLuv[5];
@@ -49,7 +49,7 @@ public class CieLuvAndHunterLabConversionTests
// Arrange
HunterLab input = new(l2, a, b);
CieLuv expected = new(l, u, v);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D50, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new HunterLab[5];
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndLmsConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndLmsConversionTests.cs
index 812ca44dd..812b2b61e 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndLmsConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndLmsConversionTests.cs
@@ -20,7 +20,7 @@ public class CieLuvAndLmsConversionTests
// Arrange
CieLuv input = new(l, u, v);
Lms expected = new(l2, m, s);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLuv[5];
@@ -49,7 +49,7 @@ public class CieLuvAndLmsConversionTests
// Arrange
Lms input = new(l2, m, s);
CieLuv expected = new(l, u, v);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new Lms[5];
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndRgbConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndRgbConversionTests.cs
index f1da6e33f..1af802326 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndRgbConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndRgbConversionTests.cs
@@ -20,7 +20,7 @@ public class CieLuvAndRgbConversionTests
// Arrange
CieLuv input = new(l, u, v);
Rgb expected = new(r, g, b);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLuv[5];
@@ -49,7 +49,7 @@ public class CieLuvAndRgbConversionTests
// Arrange
Rgb input = new(r, g, b);
CieLuv expected = new(l, u, v);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new Rgb[5];
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndYCbCrConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndYCbCrConversionTests.cs
index fa7e2ece3..62b276a1f 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndYCbCrConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLuvAndYCbCrConversionTests.cs
@@ -13,14 +13,15 @@ public class CieLuvAndYCbCrConversionTests
private static readonly ApproximateColorProfileComparer Comparer = new(.0002F);
[Theory]
- [InlineData(0, 0, 0, 0, 128, 128)]
- [InlineData(36.0555, 93.6901, 10.01514, 71.8283, 119.3174, 193.9839)]
+ [InlineData(100, 0, 0, 1, .5F, .5F)]
+ [InlineData(0, 0, 0, 0, .5F, .5F)]
+ [InlineData(53.38897F, 0, 0, .5F, .5F, .5F)]
public void Convert_CieLuv_to_YCbCr(float l, float u, float v, float y, float cb, float cr)
{
// Arrange
CieLuv input = new(l, u, v);
YCbCr expected = new(y, cb, cr);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLuv[5];
@@ -42,14 +43,15 @@ public class CieLuvAndYCbCrConversionTests
}
[Theory]
- [InlineData(0, 128, 128, 0, 0, 0)]
- [InlineData(71.8283, 119.3174, 193.9839, 36.00565, 93.44593, 10.2234)]
+ [InlineData(1, .5F, .5F, 100, 0, 0)]
+ [InlineData(0, .5F, .5F, 0, 0, 0)]
+ [InlineData(.5F, .5F, .5F, 53.38897F, 0, 0)]
public void Convert_YCbCr_to_CieLuv(float y, float cb, float cr, float l, float u, float v)
{
// Arrange
YCbCr input = new(y, cb, cr);
CieLuv expected = new(l, u, v);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new YCbCr[5];
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieLuvTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieLuvTests.cs
index db903a0bf..173491081 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieLuvTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieLuvTests.cs
@@ -9,6 +9,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
///
/// Tests the struct.
///
+[Trait("Color", "Conversion")]
public class CieLuvTests
{
[Fact]
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieXyChromaticityCoordinatesTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieXyChromaticityCoordinatesTests.cs
index a85a08a21..8bc71f1e1 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieXyChromaticityCoordinatesTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieXyChromaticityCoordinatesTests.cs
@@ -8,6 +8,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
///
/// Tests the struct.
///
+[Trait("Color", "Conversion")]
public class CieXyChromaticityCoordinatesTests
{
[Fact]
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieXyyAndYCbCrConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieXyyAndYCbCrConversionTests.cs
index 1fe359603..f9d571e03 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieXyyAndYCbCrConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieXyyAndYCbCrConversionTests.cs
@@ -13,8 +13,9 @@ public class CieXyyAndYCbCrConversionTests
private static readonly ApproximateColorProfileComparer Comparer = new(.0002f);
[Theory]
- [InlineData(0, 0, 0, 0, 128, 128)]
- [InlineData(0.360555, 0.936901, 0.1001514, 64.0204849, 91.87107, 82.33627)]
+ [InlineData(.34566915F, .358496159F, .99999994F, 1, .5F, .5F)]
+ [InlineData(0, 0, 0, 0, .5F, .5F)]
+ [InlineData(.34566915F, .358496159F, .214041144F, .5F, .5F, .5F)]
public void Convert_CieXyy_to_YCbCr(float x, float y, float yl, float y2, float cb, float cr)
{
// Arrange
@@ -41,8 +42,9 @@ public class CieXyyAndYCbCrConversionTests
}
[Theory]
- [InlineData(0, 128, 128, 0, 0, 0)]
- [InlineData(64.0204849, 91.87107, 82.33627, 0.32114, 0.59787, 0.10976)]
+ [InlineData(1, .5F, .5F, .34566915F, .358496159F, .99999994F)]
+ [InlineData(0, .5F, .5F, 0, 0, 0)]
+ [InlineData(.5F, .5F, .5F, .34566915F, .358496159F, .214041144F)]
public void Convert_YCbCr_to_CieXyy(float y2, float cb, float cr, float x, float y, float yl)
{
// Arrange
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieXyyTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieXyyTests.cs
index 245512f8a..80904c5df 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieXyyTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieXyyTests.cs
@@ -9,6 +9,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
///
/// Tests the struct.
///
+[Trait("Color", "Conversion")]
public class CieXyyTests
{
[Fact]
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLabConversionTest.cs b/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLabConversionTest.cs
index cb4d02889..76fceec41 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLabConversionTest.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLabConversionTest.cs
@@ -12,6 +12,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
/// Test data generated using:
///
///
+[Trait("Color", "Conversion")]
public class CieXyzAndCieLabConversionTest
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0001f);
@@ -29,7 +30,7 @@ public class CieXyzAndCieLabConversionTest
{
// Arrange
CieLab input = new(l, a, b);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
CieXyz expected = new(x, y, z);
@@ -62,7 +63,7 @@ public class CieXyzAndCieLabConversionTest
{
// Arrange
CieXyz input = new(x, y, z);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
CieLab expected = new(l, a, b);
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLuvConversionTest.cs b/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLuvConversionTest.cs
index 944b99005..b269818ae 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLuvConversionTest.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieLuvConversionTest.cs
@@ -29,7 +29,7 @@ public class CieXyzAndCieLuvConversionTest
CieXyz input = new(x, y, z);
CieLuv expected = new(l, u, v);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieXyz[5];
@@ -64,7 +64,7 @@ public class CieXyzAndCieLuvConversionTest
CieLuv input = new(l, u, v);
CieXyz expected = new(x, y, z);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetWhitePoint = KnownIlluminants.D65 };
ColorProfileConverter converter = new(options);
Span inputSpan = new CieLuv[5];
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieXyyConversionTest.cs b/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieXyyConversionTest.cs
index 7b1d0ac78..48bb6c1e1 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieXyyConversionTest.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndCieXyyConversionTest.cs
@@ -12,6 +12,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
/// Test data generated using:
///
///
+[Trait("Color", "Conversion")]
public class CieXyzAndCieXyyConversionTest
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0001F);
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndLmsConversionTest.cs b/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndLmsConversionTest.cs
index 185fcd256..c7898904d 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndLmsConversionTest.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndLmsConversionTest.cs
@@ -11,6 +11,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
///
/// Test data generated using original colorful library.
///
+[Trait("Color", "Conversion")]
public class CieXyzAndLmsConversionTest
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0001f);
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndYCbCrConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndYCbCrConversionTests.cs
index 475673da8..90175a058 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndYCbCrConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieXyzAndYCbCrConversionTests.cs
@@ -13,8 +13,8 @@ public class CieXyzAndYCbCrConversionTests
private static readonly ApproximateColorProfileComparer Comparer = new(.0002f);
[Theory]
- [InlineData(0, 0, 0, 0, 128, 128)]
- [InlineData(0.360555, 0.936901, 0.1001514, 149.685, 43.52769, 21.23457)]
+ [InlineData(0, 0, 0, 0, .5F, .5F)]
+ [InlineData(.206382737F, .214041144F, .176628917F, .5F, .5F, .5F)]
public void Convert_CieXyz_to_YCbCr(float x, float y, float z, float y2, float cb, float cr)
{
// Arrange
@@ -41,8 +41,8 @@ public class CieXyzAndYCbCrConversionTests
}
[Theory]
- [InlineData(0, 128, 128, 0, 0, 0)]
- [InlineData(149.685, 43.52769, 21.23457, 0.38506496, 0.716878653, 0.0971045)]
+ [InlineData(0, .5F, .5F, 0, 0, 0)]
+ [InlineData(.5F, .5F, .5F, .206382737F, .214041144F, .176628917F)]
public void Convert_YCbCr_to_CieXyz(float y2, float cb, float cr, float x, float y, float z)
{
// Arrange
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CieXyzTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CieXyzTests.cs
index 88138304a..683b3b661 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CieXyzTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CieXyzTests.cs
@@ -9,6 +9,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
///
/// Tests the struct.
///
+[Trait("Color", "Conversion")]
public class CieXyzTests
{
[Fact]
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CmykAndYCbCrConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CmykAndYCbCrConversionTests.cs
index 64b47e2b9..3a5fe7c15 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CmykAndYCbCrConversionTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CmykAndYCbCrConversionTests.cs
@@ -13,8 +13,9 @@ public class CmykAndYCbCrConversionTests
private static readonly ApproximateColorProfileComparer Comparer = new(.0002F);
[Theory]
- [InlineData(0, 0, 0, 0, 255, 128, 128)]
- [InlineData(0.360555, 0.1036901, 0.818514, 0.274615, 136.5134, 69.90555, 114.9948)]
+ [InlineData(0, 0, 0, 1, 0, .5F, .5F)]
+ [InlineData(0, 0, 0, 0, 1, .5F, .5F)]
+ [InlineData(0, .8570679F, .49999997F, 0, .439901F, .5339159F, .899500132F)]
public void Convert_Cmyk_To_YCbCr(float c, float m, float y, float k, float y2, float cb, float cr)
{
// Arrange
@@ -41,8 +42,9 @@ public class CmykAndYCbCrConversionTests
}
[Theory]
- [InlineData(255, 128, 128, 0, 0, 0, 5.960464E-08)]
- [InlineData(136.5134, 69.90555, 114.9948, 0.2891567, 0, 0.7951807, 0.3490196)]
+ [InlineData(0, .5F, .5F, 0, 0, 0, 1)]
+ [InlineData(1, .5F, .5F, 0, 0, 0, 0)]
+ [InlineData(.5F, .5F, 1F, 0, .8570679F, .49999997F, 0)]
public void Convert_YCbCr_To_Cmyk(float y2, float cb, float cr, float c, float m, float y, float k)
{
// Arrange
diff --git a/tests/ImageSharp.Tests/ColorProfiles/CmykTests.cs b/tests/ImageSharp.Tests/ColorProfiles/CmykTests.cs
index e2044a75d..22b7a7f70 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/CmykTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/CmykTests.cs
@@ -9,6 +9,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
///
/// Tests the struct.
///
+[Trait("Color", "Conversion")]
public class CmykTests
{
[Fact]
diff --git a/tests/ImageSharp.Tests/ColorProfiles/ColorProfileConverterChomaticAdaptationTests.cs b/tests/ImageSharp.Tests/ColorProfiles/ColorProfileConverterChomaticAdaptationTests.cs
index a90e5b9e8..525220d8e 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/ColorProfileConverterChomaticAdaptationTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/ColorProfileConverterChomaticAdaptationTests.cs
@@ -26,7 +26,7 @@ public class ColorProfileConverterChomaticAdaptationTests
Rgb expected = new(r2, g2, b2);
ColorConversionOptions options = new()
{
- RgbWorkingSpace = KnownRgbWorkingSpaces.WideGamutRgb,
+ SourceRgbWorkingSpace = KnownRgbWorkingSpaces.WideGamutRgb,
TargetRgbWorkingSpace = KnownRgbWorkingSpaces.SRgb
};
ColorProfileConverter converter = new(options);
@@ -49,7 +49,7 @@ public class ColorProfileConverterChomaticAdaptationTests
Rgb expected = new(r2, g2, b2);
ColorConversionOptions options = new()
{
- RgbWorkingSpace = KnownRgbWorkingSpaces.SRgb,
+ SourceRgbWorkingSpace = KnownRgbWorkingSpaces.SRgb,
TargetRgbWorkingSpace = KnownRgbWorkingSpaces.WideGamutRgb
};
ColorProfileConverter converter = new(options);
@@ -71,7 +71,7 @@ public class ColorProfileConverterChomaticAdaptationTests
CieLab expected = new(l2, a2, b2);
ColorConversionOptions options = new()
{
- WhitePoint = KnownIlluminants.D65,
+ SourceWhitePoint = KnownIlluminants.D65,
TargetWhitePoint = KnownIlluminants.D50
};
ColorProfileConverter converter = new(options);
@@ -93,7 +93,7 @@ public class ColorProfileConverterChomaticAdaptationTests
CieXyz expected = new(x2, y2, z2);
ColorConversionOptions options = new()
{
- WhitePoint = KnownIlluminants.D65,
+ SourceWhitePoint = KnownIlluminants.D65,
TargetWhitePoint = KnownIlluminants.D50,
AdaptationMatrix = KnownChromaticAdaptationMatrices.Bradford
};
@@ -117,7 +117,7 @@ public class ColorProfileConverterChomaticAdaptationTests
CieXyz expected = new(x2, y2, z2);
ColorConversionOptions options = new()
{
- WhitePoint = KnownIlluminants.D65,
+ SourceWhitePoint = KnownIlluminants.D65,
TargetWhitePoint = KnownIlluminants.D50,
AdaptationMatrix = KnownChromaticAdaptationMatrices.XyzScaling
};
@@ -141,7 +141,7 @@ public class ColorProfileConverterChomaticAdaptationTests
HunterLab expected = new(l2, a2, b2);
ColorConversionOptions options = new()
{
- WhitePoint = KnownIlluminants.D65,
+ SourceWhitePoint = KnownIlluminants.D65,
TargetWhitePoint = KnownIlluminants.D50,
};
@@ -164,7 +164,7 @@ public class ColorProfileConverterChomaticAdaptationTests
CieLchuv expected = new(l2, c2, h2);
ColorConversionOptions options = new()
{
- WhitePoint = KnownIlluminants.D65,
+ SourceWhitePoint = KnownIlluminants.D65,
TargetWhitePoint = KnownIlluminants.D50,
AdaptationMatrix = KnownChromaticAdaptationMatrices.XyzScaling
};
@@ -187,7 +187,7 @@ public class ColorProfileConverterChomaticAdaptationTests
CieLch expected = new(l2, c2, h2);
ColorConversionOptions options = new()
{
- WhitePoint = KnownIlluminants.D65,
+ SourceWhitePoint = KnownIlluminants.D65,
TargetWhitePoint = KnownIlluminants.D50,
AdaptationMatrix = KnownChromaticAdaptationMatrices.XyzScaling
};
diff --git a/tests/ImageSharp.Tests/ColorProfiles/HslTests.cs b/tests/ImageSharp.Tests/ColorProfiles/HslTests.cs
index d18e65117..6697cbfde 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/HslTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/HslTests.cs
@@ -9,6 +9,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
///
/// Tests the struct.
///
+[Trait("Color", "Conversion")]
public class HslTests
{
[Fact]
diff --git a/tests/ImageSharp.Tests/ColorProfiles/HsvTests.cs b/tests/ImageSharp.Tests/ColorProfiles/HsvTests.cs
index 46f58b18e..dd71fcd3f 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/HsvTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/HsvTests.cs
@@ -9,6 +9,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
///
/// Tests the struct.
///
+[Trait("Color", "Conversion")]
public class HsvTests
{
[Fact]
diff --git a/tests/ImageSharp.Tests/ColorProfiles/HunterLabTests.cs b/tests/ImageSharp.Tests/ColorProfiles/HunterLabTests.cs
index 5fbdd0788..af06b3c91 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/HunterLabTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/HunterLabTests.cs
@@ -9,6 +9,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
///
/// Tests the struct.
///
+[Trait("Color", "Conversion")]
public class HunterLabTests
{
[Fact]
diff --git a/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/ClutCalculatorTests.cs b/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/ClutCalculatorTests.cs
new file mode 100644
index 000000000..249e7f4ed
--- /dev/null
+++ b/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/ClutCalculatorTests.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Numerics;
+using SixLabors.ImageSharp.ColorProfiles.Icc.Calculators;
+using SixLabors.ImageSharp.Metadata.Profiles.Icc;
+using SixLabors.ImageSharp.Tests.TestDataIcc.Conversion;
+
+namespace SixLabors.ImageSharp.Tests.ColorProfiles.Icc.Calculators;
+
+///
+/// Tests ICC
+///
+[Trait("Color", "Conversion")]
+public class ClutCalculatorTests
+{
+ [Theory]
+ [MemberData(nameof(IccConversionDataClut.ClutConversionTestData), MemberType = typeof(IccConversionDataClut))]
+ internal void ClutCalculator_WithClut_ReturnsResult(IccClut lut, Vector4 input, Vector4 expected)
+ {
+ ClutCalculator calculator = new(lut);
+
+ Vector4 result = calculator.Calculate(input);
+
+ VectorAssert.Equal(expected, result, 4);
+ }
+}
diff --git a/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/CurveCalculatorTests.cs b/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/CurveCalculatorTests.cs
new file mode 100644
index 000000000..8f48277d6
--- /dev/null
+++ b/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/CurveCalculatorTests.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.ColorProfiles.Conversion.Icc;
+using SixLabors.ImageSharp.Metadata.Profiles.Icc;
+using SixLabors.ImageSharp.Tests.TestDataIcc.Conversion;
+
+namespace SixLabors.ImageSharp.Tests.ColorProfiles.Icc.Calculators;
+
+///
+/// Tests ICC
+///
+[Trait("Color", "Conversion")]
+public class CurveCalculatorTests
+{
+ [Theory]
+ [MemberData(nameof(IccConversionDataTrc.CurveConversionTestData), MemberType = typeof(IccConversionDataTrc))]
+ internal void CurveCalculator_WithCurveEntry_ReturnsResult(IccCurveTagDataEntry curve, bool inverted, float input, float expected)
+ {
+ CurveCalculator calculator = new(curve, inverted);
+
+ float result = calculator.Calculate(input);
+
+ Assert.Equal(expected, result, 4f);
+ }
+}
diff --git a/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/LutABCalculatorTests.cs b/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/LutABCalculatorTests.cs
new file mode 100644
index 000000000..de2b4f5fa
--- /dev/null
+++ b/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/LutABCalculatorTests.cs
@@ -0,0 +1,38 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Numerics;
+using SixLabors.ImageSharp.ColorProfiles.Conversion.Icc;
+using SixLabors.ImageSharp.Metadata.Profiles.Icc;
+using SixLabors.ImageSharp.Tests.TestDataIcc.Conversion;
+
+namespace SixLabors.ImageSharp.Tests.ColorProfiles.Icc.Calculators;
+
+///
+/// Tests ICC
+///
+[Trait("Color", "Conversion")]
+public class LutABCalculatorTests
+{
+ [Theory]
+ [MemberData(nameof(IccConversionDataLutAB.LutAToBConversionTestData), MemberType = typeof(IccConversionDataLutAB))]
+ internal void LutABCalculator_WithLutAToB_ReturnsResult(IccLutAToBTagDataEntry lut, Vector4 input, Vector4 expected)
+ {
+ LutABCalculator calculator = new(lut);
+
+ Vector4 result = calculator.Calculate(input);
+
+ VectorAssert.Equal(expected, result, 4);
+ }
+
+ [Theory]
+ [MemberData(nameof(IccConversionDataLutAB.LutBToAConversionTestData), MemberType = typeof(IccConversionDataLutAB))]
+ internal void LutABCalculator_WithLutBToA_ReturnsResult(IccLutBToATagDataEntry lut, Vector4 input, Vector4 expected)
+ {
+ LutABCalculator calculator = new(lut);
+
+ Vector4 result = calculator.Calculate(input);
+
+ VectorAssert.Equal(expected, result, 4);
+ }
+}
diff --git a/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/LutCalculatorTests.cs b/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/LutCalculatorTests.cs
new file mode 100644
index 000000000..6cc77247a
--- /dev/null
+++ b/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/LutCalculatorTests.cs
@@ -0,0 +1,25 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.ColorProfiles.Icc.Calculators;
+using SixLabors.ImageSharp.Tests.TestDataIcc.Conversion;
+
+namespace SixLabors.ImageSharp.Tests.ColorProfiles.Icc.Calculators;
+
+///
+/// Tests ICC
+///
+[Trait("Color", "Conversion")]
+public class LutCalculatorTests
+{
+ [Theory]
+ [MemberData(nameof(IccConversionDataLut.LutConversionTestData), MemberType = typeof(IccConversionDataLut))]
+ internal void LutCalculator_WithLut_ReturnsResult(float[] lut, bool inverted, float input, float expected)
+ {
+ LutCalculator calculator = new(lut, inverted);
+
+ float result = calculator.Calculate(input);
+
+ Assert.Equal(expected, result, 4f);
+ }
+}
diff --git a/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/LutEntryCalculatorTests.cs b/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/LutEntryCalculatorTests.cs
new file mode 100644
index 000000000..14f1386eb
--- /dev/null
+++ b/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/LutEntryCalculatorTests.cs
@@ -0,0 +1,38 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Numerics;
+using SixLabors.ImageSharp.ColorProfiles.Icc.Calculators;
+using SixLabors.ImageSharp.Metadata.Profiles.Icc;
+using SixLabors.ImageSharp.Tests.TestDataIcc.Conversion;
+
+namespace SixLabors.ImageSharp.Tests.ColorProfiles.Icc.Calculators;
+
+///
+/// Tests ICC
+///
+[Trait("Color", "Conversion")]
+public class LutEntryCalculatorTests
+{
+ [Theory]
+ [MemberData(nameof(IccConversionDataLutEntry.Lut8ConversionTestData), MemberType = typeof(IccConversionDataLutEntry))]
+ internal void LutEntryCalculator_WithLut8_ReturnsResult(IccLut8TagDataEntry lut, Vector4 input, Vector4 expected)
+ {
+ LutEntryCalculator calculator = new(lut);
+
+ Vector4 result = calculator.Calculate(input);
+
+ VectorAssert.Equal(expected, result, 4);
+ }
+
+ [Theory]
+ [MemberData(nameof(IccConversionDataLutEntry.Lut16ConversionTestData), MemberType = typeof(IccConversionDataLutEntry))]
+ internal void LutEntryCalculator_WithLut16_ReturnsResult(IccLut16TagDataEntry lut, Vector4 input, Vector4 expected)
+ {
+ LutEntryCalculator calculator = new(lut);
+
+ Vector4 result = calculator.Calculate(input);
+
+ VectorAssert.Equal(expected, result, 4);
+ }
+}
diff --git a/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/MatrixCalculatorTests.cs b/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/MatrixCalculatorTests.cs
new file mode 100644
index 000000000..f56bf5873
--- /dev/null
+++ b/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/MatrixCalculatorTests.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Numerics;
+using SixLabors.ImageSharp.ColorProfiles.Icc.Calculators;
+using SixLabors.ImageSharp.Tests.TestDataIcc.Conversion;
+
+namespace SixLabors.ImageSharp.Tests.ColorProfiles.Icc.Calculators;
+
+///
+/// Tests ICC
+///
+[Trait("Color", "Conversion")]
+public class MatrixCalculatorTests
+{
+ [Theory]
+ [MemberData(nameof(IccConversionDataMatrix.MatrixConversionTestData), MemberType = typeof(IccConversionDataMatrix))]
+ internal void MatrixCalculator_WithMatrix_ReturnsResult(Matrix4x4 matrix2D, Vector3 matrix1D, Vector4 input, Vector4 expected)
+ {
+ MatrixCalculator calculator = new(matrix2D, matrix1D);
+
+ Vector4 result = calculator.Calculate(input);
+
+ VectorAssert.Equal(expected, result, 4);
+ }
+}
diff --git a/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/ParametricCurveCalculatorTests.cs b/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/ParametricCurveCalculatorTests.cs
new file mode 100644
index 000000000..aac3f42c9
--- /dev/null
+++ b/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/ParametricCurveCalculatorTests.cs
@@ -0,0 +1,26 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.ColorProfiles.Icc.Calculators;
+using SixLabors.ImageSharp.Metadata.Profiles.Icc;
+using SixLabors.ImageSharp.Tests.TestDataIcc.Conversion;
+
+namespace SixLabors.ImageSharp.Tests.ColorProfiles.Icc.Calculators;
+
+///
+/// Tests ICC
+///
+[Trait("Color", "Conversion")]
+public class ParametricCurveCalculatorTests
+{
+ [Theory]
+ [MemberData(nameof(IccConversionDataTrc.ParametricCurveConversionTestData), MemberType = typeof(IccConversionDataTrc))]
+ internal void ParametricCurveCalculator_WithCurveEntry_ReturnsResult(IccParametricCurveTagDataEntry curve, bool inverted, float input, float expected)
+ {
+ ParametricCurveCalculator calculator = new(curve, inverted);
+
+ float result = calculator.Calculate(input);
+
+ Assert.Equal(expected, result, 4f);
+ }
+}
diff --git a/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/TrcCalculatorTests.cs b/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/TrcCalculatorTests.cs
new file mode 100644
index 000000000..65f02c3fb
--- /dev/null
+++ b/tests/ImageSharp.Tests/ColorProfiles/Icc/Calculators/TrcCalculatorTests.cs
@@ -0,0 +1,27 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Numerics;
+using SixLabors.ImageSharp.ColorProfiles.Icc.Calculators;
+using SixLabors.ImageSharp.Metadata.Profiles.Icc;
+using SixLabors.ImageSharp.Tests.TestDataIcc.Conversion;
+
+namespace SixLabors.ImageSharp.Tests.ColorProfiles.Icc.Calculators;
+
+///
+/// Tests ICC
+///
+[Trait("Color", "Conversion")]
+public class TrcCalculatorTests
+{
+ [Theory]
+ [MemberData(nameof(IccConversionDataTrc.TrcArrayConversionTestData), MemberType = typeof(IccConversionDataTrc))]
+ internal void TrcCalculator_WithCurvesArray_ReturnsResult(IccTagDataEntry[] entries, bool inverted, Vector4 input, Vector4 expected)
+ {
+ TrcCalculator calculator = new(entries, inverted);
+
+ Vector4 result = calculator.Calculate(input);
+
+ VectorAssert.Equal(expected, result, 4);
+ }
+}
diff --git a/tests/ImageSharp.Tests/ColorProfiles/Icc/ColorProfileConverterTests.Icc.cs b/tests/ImageSharp.Tests/ColorProfiles/Icc/ColorProfileConverterTests.Icc.cs
new file mode 100644
index 000000000..cb349af96
--- /dev/null
+++ b/tests/ImageSharp.Tests/ColorProfiles/Icc/ColorProfileConverterTests.Icc.cs
@@ -0,0 +1,263 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Numerics;
+using SixLabors.ImageSharp.ColorProfiles;
+using SixLabors.ImageSharp.Metadata.Profiles.Icc;
+using Wacton.Unicolour;
+using Wacton.Unicolour.Icc;
+using Xunit.Abstractions;
+using Rgb = SixLabors.ImageSharp.ColorProfiles.Rgb;
+
+namespace SixLabors.ImageSharp.Tests.ColorProfiles.Icc;
+
+public class ColorProfileConverterTests(ITestOutputHelper testOutputHelper)
+{
+ // for 3-channel spaces, 4th item is ignored
+ private static readonly List Inputs =
+ [
+ [0, 0, 0, 0],
+ [1, 0, 0, 0],
+ [0, 1, 0, 0],
+ [0, 0, 1, 0],
+ [0, 0, 0, 1],
+ [1, 1, 1, 1],
+ [0.5f, 0.5f, 0.5f, 0.5f],
+ [0.199678659f, 0.67982769f, 0.805381715f, 0.982666492f], // requires clipping before source is PCS adjusted for Fogra39 -> sRGBv2
+ [0.776568174f, 0.961630166f, 0.31032759f, 0.895294666f], // requires clipping after target is PCS adjusted for Fogra39 -> sRGBv2
+ [GetNormalizedRandomValue(), GetNormalizedRandomValue(), GetNormalizedRandomValue(), GetNormalizedRandomValue()]
+ ];
+
+ [Theory]
+ [InlineData(TestIccProfiles.Fogra39, TestIccProfiles.Fogra39)] // CMYK -> LAB -> CMYK (commonly used v2 profiles)
+ [InlineData(TestIccProfiles.Fogra39, TestIccProfiles.Swop2006)] // CMYK -> LAB -> CMYK (commonly used v2 profiles)
+ [InlineData(TestIccProfiles.Swop2006, TestIccProfiles.Fogra39)] // CMYK -> LAB -> CMYK (commonly used v2 profiles)
+ [InlineData(TestIccProfiles.Swop2006, TestIccProfiles.Swop2006)] // CMYK -> LAB -> CMYK (commonly used v2 profiles)
+ [InlineData(TestIccProfiles.Fogra39, TestIccProfiles.JapanColor2003)] // CMYK -> LAB -> CMYK (different bit depth v2 LUTs, 8-bit vs 16-bit)
+ [InlineData(TestIccProfiles.JapanColor2011, TestIccProfiles.Fogra39)] // CMYK -> LAB -> CMYK (different LUT versions, v2 vs v4)
+ [InlineData(TestIccProfiles.Fogra39, TestIccProfiles.Cgats21)] // CMYK -> LAB -> RGB (different LUT versions, v2 vs v4)
+ [InlineData(TestIccProfiles.Fogra39, TestIccProfiles.StandardRgbV4)] // RGB -> LAB -> CMYK (different LUT versions, v4 vs v2)
+ [InlineData(TestIccProfiles.StandardRgbV4, TestIccProfiles.Fogra39)] // RGB -> LAB -> XYZ -> RGB (different LUT elements, B-Matrix-M-CLUT-A vs B-Matrix-M)
+ [InlineData(TestIccProfiles.StandardRgbV4, TestIccProfiles.RommRgb)] // RGB -> XYZ -> LAB -> RGB (different LUT elements, B-Matrix-M vs B-Matrix-M-CLUT-A)
+ [InlineData(TestIccProfiles.RommRgb, TestIccProfiles.StandardRgbV4)] // CMYK -> LAB -> CMYK (different bit depth v2 LUTs, 16-bit vs 8-bit)
+ [InlineData(TestIccProfiles.Fogra39, TestIccProfiles.StandardRgbV2, 0.0005)] // CMYK -> LAB -> XYZ -> RGB (different LUT tags, A2B vs TRC) --- tolerance slightly higher due to difference in inverse curve implementation
+ [InlineData(TestIccProfiles.StandardRgbV2, TestIccProfiles.Fogra39)] // RGB -> XYZ -> LAB -> CMYK (different LUT tags, TRC vs A2B)
+ public void CanConvertIccProfiles(string sourceProfile, string targetProfile, double tolerance = 0.000005)
+ {
+ List actual = Inputs.ConvertAll(input => GetActualTargetValues(input, sourceProfile, targetProfile));
+ AssertConversion(sourceProfile, targetProfile, actual, tolerance, testOutputHelper);
+ }
+
+ [Theory]
+ [InlineData(TestIccProfiles.Fogra39, TestIccProfiles.Fogra39)] // CMYK -> LAB -> CMYK (commonly used v2 profiles)
+ [InlineData(TestIccProfiles.Fogra39, TestIccProfiles.Swop2006)] // CMYK -> LAB -> CMYK (commonly used v2 profiles)
+ [InlineData(TestIccProfiles.Swop2006, TestIccProfiles.Fogra39)] // CMYK -> LAB -> CMYK (commonly used v2 profiles)
+ [InlineData(TestIccProfiles.Swop2006, TestIccProfiles.Swop2006)] // CMYK -> LAB -> CMYK (commonly used v2 profiles)
+ [InlineData(TestIccProfiles.Fogra39, TestIccProfiles.JapanColor2003)] // CMYK -> LAB -> CMYK (different bit depth v2 LUTs, 8-bit vs 16-bit)
+ [InlineData(TestIccProfiles.JapanColor2011, TestIccProfiles.Fogra39)] // CMYK -> LAB -> CMYK (different LUT versions, v2 vs v4)
+ [InlineData(TestIccProfiles.Fogra39, TestIccProfiles.Cgats21)] // CMYK -> LAB -> RGB (different LUT versions, v2 vs v4)
+ [InlineData(TestIccProfiles.Fogra39, TestIccProfiles.StandardRgbV4)] // RGB -> LAB -> CMYK (different LUT versions, v4 vs v2)
+ [InlineData(TestIccProfiles.StandardRgbV4, TestIccProfiles.Fogra39)] // RGB -> LAB -> XYZ -> RGB (different LUT elements, B-Matrix-M-CLUT-A vs B-Matrix-M)
+ [InlineData(TestIccProfiles.StandardRgbV4, TestIccProfiles.RommRgb)] // RGB -> XYZ -> LAB -> RGB (different LUT elements, B-Matrix-M vs B-Matrix-M-CLUT-A)
+ [InlineData(TestIccProfiles.RommRgb, TestIccProfiles.StandardRgbV4)] // CMYK -> LAB -> CMYK (different bit depth v2 LUTs, 16-bit vs 8-bit)
+ [InlineData(TestIccProfiles.Fogra39, TestIccProfiles.StandardRgbV2, 0.0005)] // CMYK -> LAB -> XYZ -> RGB (different LUT tags, A2B vs TRC) --- tolerance slightly higher due to difference in inverse curve implementation
+ [InlineData(TestIccProfiles.StandardRgbV2, TestIccProfiles.Fogra39)] // RGB -> XYZ -> LAB -> CMYK (different LUT tags, TRC vs A2B)
+ [InlineData(TestIccProfiles.Issue129, TestIccProfiles.StandardRgbV4)] // CMYK -> LAB -> -> XYZ -> RGB
+ public void CanBulkConvertIccProfiles(string sourceProfile, string targetProfile, double tolerance = 0.000005)
+ {
+ List actual = GetBulkActualTargetValues(Inputs, sourceProfile, targetProfile);
+ AssertConversion(sourceProfile, targetProfile, actual, tolerance, testOutputHelper);
+ }
+
+ private static void AssertConversion(string sourceProfile, string targetProfile, List actual, double tolerance, ITestOutputHelper testOutputHelper)
+ {
+ List expected = Inputs.ConvertAll(input => GetExpectedTargetValues(sourceProfile, targetProfile, input, testOutputHelper));
+ Assert.Equal(expected.Count, actual.Count);
+
+ for (int i = 0; i < expected.Count; i++)
+ {
+ Log(testOutputHelper, Inputs[i], expected[i], actual[i]);
+ for (int j = 0; j < expected[i].Length; j++)
+ {
+ Assert.Equal(expected[i][j], actual[i][j], tolerance);
+ }
+ }
+ }
+
+ private static double[] GetExpectedTargetValues(string sourceProfile, string targetProfile, float[] input, ITestOutputHelper testOutputHelper)
+ {
+ Wacton.Unicolour.Configuration sourceConfig = TestIccProfiles.GetUnicolourConfiguration(sourceProfile);
+ Wacton.Unicolour.Configuration targetConfig = TestIccProfiles.GetUnicolourConfiguration(targetProfile);
+
+ if (sourceConfig.Icc.Error != null || targetConfig.Icc.Error != null)
+ {
+ Assert.Fail("Unicolour does not support the ICC profile - test values will need to be calculated manually");
+ }
+
+ /* This is a hack to trick Unicolour to work in the same way as ImageSharp.
+ * ImageSharp bypasses PCS adjustment for v2 perceptual intent if source and target both need it
+ * as they both share the same understanding of what the PCS is (see ColorProfileConverterExtensionsIcc.GetTargetPcsWithPerceptualAdjustment)
+ * Unicolour does not support a direct profile-to-profile conversion so will always perform PCS adjustment for v2 perceptual intent.
+ * However, PCS adjustment clips negative XYZ values, causing those particular values in Unicolour and ImageSharp to diverge.
+ * It's unclear to me if there's a fundamental correct answer here.
+ *
+ * There are two obvious ways to keep Unicolour and ImageSharp values aligned:
+ * 1. Make ImageSharp always perform PCS adjustment, clipping negative XYZ values during the process - but creates a lot more calculations
+ * 2. Make Unicolour stop performing PCS adjustment, allowing negative XYZ values during conversion
+ *
+ * Option 2 is implemented by modifying the profiles so they claim to be v4 profiles
+ * since v4 perceptual profiles do not apply PCS adjustment.
+ */
+ bool isSourcePerceptualV2 = sourceConfig.Icc.Intent == Intent.Perceptual && sourceConfig.Icc.Profile!.Header.ProfileVersion.Major == 2;
+ bool isTargetPerceptualV2 = targetConfig.Icc.Intent == Intent.Perceptual && targetConfig.Icc.Profile!.Header.ProfileVersion.Major == 2;
+ if (isSourcePerceptualV2 && isTargetPerceptualV2)
+ {
+ sourceConfig = GetUnicolourConfigAsV4Header(sourceConfig);
+ targetConfig = GetUnicolourConfigAsV4Header(targetConfig);
+ }
+
+ Channels channels = new([.. input.Select(value => (double)value)]);
+ Unicolour source = new(sourceConfig, channels);
+ Unicolour target = source.ConvertToConfiguration(targetConfig);
+ if (target.Icc.Error != null)
+ {
+ testOutputHelper.WriteLine($"Error during Unicolour ICC conversion of supported profile: {target.Icc.Error}");
+ }
+
+ return target.Icc.Values;
+ }
+
+ private static Wacton.Unicolour.Configuration GetUnicolourConfigAsV4Header(Wacton.Unicolour.Configuration config)
+ {
+ string profilePath = config.Icc.Profile!.FileInfo.FullName;
+ string modifiedFilename = $"{Path.GetFileNameWithoutExtension(profilePath)}_modified.icc";
+ string modifiedProfile = Path.Combine(Path.GetDirectoryName(profilePath)!, modifiedFilename);
+
+ Wacton.Unicolour.Configuration modifiedConfig;
+ if (!TestIccProfiles.HasUnicolourConfiguration(modifiedProfile))
+ {
+ byte[] bytes = File.ReadAllBytes(profilePath);
+ bytes[8] = 4; // byte 8 of profile is major version
+ File.WriteAllBytes(modifiedProfile, bytes);
+ modifiedConfig = TestIccProfiles.GetUnicolourConfiguration(modifiedProfile);
+ File.Delete(modifiedProfile);
+ }
+ else
+ {
+ modifiedConfig = TestIccProfiles.GetUnicolourConfiguration(modifiedProfile);
+ }
+
+ return modifiedConfig;
+ }
+
+ private static Vector4 GetActualTargetValues(float[] input, string sourceProfile, string targetProfile)
+ {
+ ColorProfileConverter converter = new(new ColorConversionOptions
+ {
+ SourceIccProfile = TestIccProfiles.GetProfile(sourceProfile),
+ TargetIccProfile = TestIccProfiles.GetProfile(targetProfile)
+ });
+
+ IccColorSpaceType sourceDataSpace = converter.Options.SourceIccProfile!.Header.DataColorSpace;
+ IccColorSpaceType targetDataSpace = converter.Options.TargetIccProfile!.Header.DataColorSpace;
+ return sourceDataSpace switch
+ {
+ IccColorSpaceType.Cmyk when targetDataSpace == IccColorSpaceType.Cmyk
+ => converter.Convert(new Cmyk(new Vector4(input))).ToScaledVector4(),
+ IccColorSpaceType.Cmyk when targetDataSpace == IccColorSpaceType.Rgb
+ => converter.Convert(new Cmyk(new Vector4(input))).ToScaledVector4(),
+ IccColorSpaceType.Rgb when targetDataSpace == IccColorSpaceType.Cmyk
+ => converter.Convert(new Rgb(new Vector3(input))).ToScaledVector4(),
+ IccColorSpaceType.Rgb when targetDataSpace == IccColorSpaceType.Rgb
+ => converter.Convert(new Rgb(new Vector3(input))).ToScaledVector4(),
+ _ => throw new NotSupportedException($"Unsupported ICC profile data color space conversion: {sourceDataSpace} -> {targetDataSpace}")
+ };
+ }
+
+ private static List GetBulkActualTargetValues(List inputs, string sourceProfile, string targetProfile)
+ {
+ ColorProfileConverter converter = new(new ColorConversionOptions
+ {
+ SourceIccProfile = TestIccProfiles.GetProfile(sourceProfile),
+ TargetIccProfile = TestIccProfiles.GetProfile(targetProfile)
+ });
+
+ IccColorSpaceType sourceDataSpace = converter.Options.SourceIccProfile!.Header.DataColorSpace;
+ IccColorSpaceType targetDataSpace = converter.Options.TargetIccProfile!.Header.DataColorSpace;
+
+ switch (sourceDataSpace)
+ {
+ case IccColorSpaceType.Cmyk:
+ {
+ Span inputSpan = inputs.Select(x => new Cmyk(new Vector4(x))).ToArray();
+
+ switch (targetDataSpace)
+ {
+ case IccColorSpaceType.Cmyk:
+ {
+ Span outputSpan = stackalloc Cmyk[inputs.Count];
+ converter.Convert(inputSpan, outputSpan);
+ return [.. outputSpan.ToArray().Select(x => x.ToScaledVector4())];
+ }
+
+ case IccColorSpaceType.Rgb:
+ {
+ Span outputSpan = stackalloc Rgb[inputs.Count];
+ converter.Convert(inputSpan, outputSpan);
+ return [.. outputSpan.ToArray().Select(x => x.ToScaledVector4())];
+ }
+
+ default:
+ throw new NotSupportedException($"Unsupported ICC profile data color space conversion: {sourceDataSpace} -> {targetDataSpace}");
+ }
+ }
+
+ case IccColorSpaceType.Rgb:
+ {
+ Span inputSpan = inputs.Select(x => new Rgb(new Vector3(x))).ToArray();
+
+ switch (targetDataSpace)
+ {
+ case IccColorSpaceType.Cmyk:
+ {
+ Span outputSpan = stackalloc Cmyk[inputs.Count];
+ converter.Convert(inputSpan, outputSpan);
+ return [.. outputSpan.ToArray().Select(x => x.ToScaledVector4())];
+ }
+
+ case IccColorSpaceType.Rgb:
+ {
+ Span outputSpan = stackalloc Rgb[inputs.Count];
+ converter.Convert(inputSpan, outputSpan);
+ return [.. outputSpan.ToArray().Select(x => x.ToScaledVector4())];
+ }
+
+ default:
+ throw new NotSupportedException($"Unsupported ICC profile data color space conversion: {sourceDataSpace} -> {targetDataSpace}");
+ }
+ }
+
+ default:
+ throw new NotSupportedException($"Unsupported ICC profile data color space conversion: {sourceDataSpace} -> {targetDataSpace}");
+ }
+ }
+
+ private static float GetNormalizedRandomValue()
+ {
+ // Generate a random value between 0 (inclusive) and 1 (exclusive).
+ double value = Random.Shared.NextDouble();
+
+ // If the random value is exactly 0, return 0F to ensure inclusivity at the lower bound.
+ // For non-zero values, add a small increment (0.0000001F) to ensure the range
+ // is inclusive at the upper bound while retaining precision.
+ // Clamp the result between 0 and 1 to ensure it does not exceed the bounds.
+ return value == 0 ? 0F : Math.Clamp((float)value + 0.0000001F, 0, 1);
+ }
+
+ private static void Log(ITestOutputHelper testOutputHelper, float[] input, double[] expected, Vector4 actual)
+ {
+ string inputText = string.Join(", ", input);
+ string expectedText = string.Join(", ", expected.Select(x => $"{x:f8}"));
+ testOutputHelper.WriteLine($"Input {inputText} · Expected output {expectedText} · Actual output {actual}");
+ }
+}
diff --git a/tests/ImageSharp.Tests/ColorProfiles/Icc/TestIccProfiles.cs b/tests/ImageSharp.Tests/ColorProfiles/Icc/TestIccProfiles.cs
new file mode 100644
index 000000000..eec27fcd7
--- /dev/null
+++ b/tests/ImageSharp.Tests/ColorProfiles/Icc/TestIccProfiles.cs
@@ -0,0 +1,74 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using System.Collections.Concurrent;
+using SixLabors.ImageSharp.Metadata.Profiles.Icc;
+using Wacton.Unicolour;
+using Wacton.Unicolour.Icc;
+
+namespace SixLabors.ImageSharp.Tests.ColorProfiles.Icc;
+
+internal static class TestIccProfiles
+{
+ private static readonly ConcurrentDictionary ProfileCache = new();
+ private static readonly ConcurrentDictionary UnicolourConfigurationCache = new();
+
+ ///
+ /// v2 CMYK -> LAB, output, lut16
+ ///
+ public const string Fogra39 = "Coated_Fogra39L_VIGC_300.icc";
+
+ ///
+ /// v2 CMYK -> LAB, output, lut16
+ ///
+ public const string Swop2006 = "SWOP2006_Coated5v2.icc";
+
+ ///
+ /// v2 CMYK -> LAB, output, lut8 (A2B tags)
+ ///
+ public const string JapanColor2011 = "JapanColor2011Coated.icc";
+
+ ///
+ /// v2 CMYK -> LAB, output, lut8 (B2A tags)
+ ///
+ public const string JapanColor2003 = "JapanColor2003WebCoated.icc";
+
+ ///
+ /// v4 CMYK -> LAB, output, lutAToB: B-CLUT-A
+ ///
+ public const string Cgats21 = "CGATS21_CRPC7.icc";
+
+ ///
+ /// v4 RGB -> XYZ, colorspace, lutAToB: B-Matrix-M [only intent 0]
+ ///
+ public const string RommRgb = "ISO22028-2_ROMM-RGB.icc";
+
+ ///
+ /// v4 RGB -> LAB, colorspace, lutAToB: B-Matrix-M-CLUT-A [only intent 0 & 1]
+ ///
+ public const string StandardRgbV4 = "sRGB_v4_ICC_preference.icc";
+
+ ///
+ /// v2 CMYK -> LAB, output
+ ///
+ public const string Issue129 = "issue-129.icc";
+
+ ///
+ /// v2 RGB -> XYZ, display, TRCs
+ ///
+ public const string StandardRgbV2 = "sRGB2014.icc";
+
+ public static IccProfile GetProfile(string file)
+ => ProfileCache.GetOrAdd(file, f => new IccProfile(File.ReadAllBytes(GetFullPath(f))));
+
+ public static Wacton.Unicolour.Configuration GetUnicolourConfiguration(string file)
+ => UnicolourConfigurationCache.GetOrAdd(
+ file,
+ f => new Wacton.Unicolour.Configuration(iccConfig: new IccConfiguration(GetFullPath(f), Intent.Unspecified, f)));
+
+ public static bool HasUnicolourConfiguration(string file)
+ => UnicolourConfigurationCache.ContainsKey(file);
+
+ private static string GetFullPath(string file)
+ => Path.GetFullPath(Path.Combine(".", "TestDataIcc", "Profiles", file));
+}
diff --git a/tests/ImageSharp.Tests/ColorProfiles/LmsTests.cs b/tests/ImageSharp.Tests/ColorProfiles/LmsTests.cs
index 138fd544d..395b547fd 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/LmsTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/LmsTests.cs
@@ -9,6 +9,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
///
/// Tests the struct.
///
+[Trait("Color", "Conversion")]
public class LmsTests
{
[Fact]
diff --git a/tests/ImageSharp.Tests/ColorProfiles/RbgAndYConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/RbgAndYConversionTests.cs
new file mode 100644
index 000000000..017ba78d0
--- /dev/null
+++ b/tests/ImageSharp.Tests/ColorProfiles/RbgAndYConversionTests.cs
@@ -0,0 +1,84 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.ColorProfiles;
+
+namespace SixLabors.ImageSharp.Tests.ColorProfiles;
+
+///
+/// Tests - conversions.
+///
+///
+/// Test data generated mathematically
+///
+public class RbgAndYConversionTests
+{
+ private static readonly ApproximateColorProfileComparer Comparer = new(.001F);
+
+ [Theory]
+ [InlineData(0F, 0F, 0F, 0F)]
+ [InlineData(0.5F, 0.5F, 0.5F, 0.5F)]
+ [InlineData(1F, 1F, 1F, 1F)]
+ public void Convert_Rgb_To_Y_BT601(float r, float g, float b, float y)
+ {
+ ColorConversionOptions options = new()
+ {
+ YCbCrTransform = KnownYCbCrMatrices.BT601
+ };
+
+ Convert_Rgb_To_Y_Core(r, g, b, y, options);
+ }
+
+ [Theory]
+ [InlineData(0F, 0F, 0F, 0F)]
+ [InlineData(0.5F, 0.5F, 0.5F, 0.5F)]
+ [InlineData(1F, 1F, 1F, 1F)]
+ public void Convert_Rgb_To_Y_BT709(float r, float g, float b, float y)
+ {
+ ColorConversionOptions options = new()
+ {
+ YCbCrTransform = KnownYCbCrMatrices.BT709
+ };
+
+ Convert_Rgb_To_Y_Core(r, g, b, y, options);
+ }
+
+ [Theory]
+ [InlineData(0F, 0F, 0F, 0F)]
+ [InlineData(0.5F, 0.5F, 0.5F, 0.49999997F)]
+ [InlineData(1F, 1F, 1F, 0.99999994F)]
+ public void Convert_Rgb_To_Y_BT2020(float r, float g, float b, float y)
+ {
+ ColorConversionOptions options = new()
+ {
+ YCbCrTransform = KnownYCbCrMatrices.BT2020
+ };
+
+ Convert_Rgb_To_Y_Core(r, g, b, y, options);
+ }
+
+ private static void Convert_Rgb_To_Y_Core(float r, float g, float b, float y, ColorConversionOptions options)
+ {
+ // Arrange
+ Rgb input = new(r, g, b);
+ Y expected = new(y);
+ ColorProfileConverter converter = new(options);
+
+ Span inputSpan = new Rgb[5];
+ inputSpan.Fill(input);
+
+ Span actualSpan = new Y[5];
+
+ // Act
+ Y actual = converter.Convert(input);
+ converter.Convert(inputSpan, actualSpan);
+
+ // Assert
+ Assert.Equal(expected, actual, Comparer);
+
+ for (int i = 0; i < actualSpan.Length; i++)
+ {
+ Assert.Equal(expected, actualSpan[i], Comparer);
+ }
+ }
+}
diff --git a/tests/ImageSharp.Tests/ColorProfiles/RgbAndCieXyzConversionTest.cs b/tests/ImageSharp.Tests/ColorProfiles/RgbAndCieXyzConversionTest.cs
index c10aa2c3c..7b48089c7 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/RgbAndCieXyzConversionTest.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/RgbAndCieXyzConversionTest.cs
@@ -27,7 +27,7 @@ public class RgbAndCieXyzConversionTest
{
// Arrange
CieXyz input = new(x, y, z);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D50, TargetRgbWorkingSpace = KnownRgbWorkingSpaces.SRgb };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D50, TargetRgbWorkingSpace = KnownRgbWorkingSpaces.SRgb };
ColorProfileConverter converter = new(options);
Rgb expected = new(r, g, b);
@@ -60,7 +60,7 @@ public class RgbAndCieXyzConversionTest
{
// Arrange
CieXyz input = new(x, y, z);
- ColorConversionOptions options = new() { WhitePoint = KnownIlluminants.D65, TargetRgbWorkingSpace = KnownRgbWorkingSpaces.SRgb };
+ ColorConversionOptions options = new() { SourceWhitePoint = KnownIlluminants.D65, TargetRgbWorkingSpace = KnownRgbWorkingSpaces.SRgb };
ColorProfileConverter converter = new(options);
Rgb expected = new(r, g, b);
@@ -93,7 +93,7 @@ public class RgbAndCieXyzConversionTest
{
// Arrange
Rgb input = new(r, g, b);
- ColorConversionOptions options = new() { TargetWhitePoint = KnownIlluminants.D50, RgbWorkingSpace = KnownRgbWorkingSpaces.SRgb };
+ ColorConversionOptions options = new() { TargetWhitePoint = KnownIlluminants.D50, SourceRgbWorkingSpace = KnownRgbWorkingSpaces.SRgb };
ColorProfileConverter converter = new(options);
CieXyz expected = new(x, y, z);
@@ -126,7 +126,7 @@ public class RgbAndCieXyzConversionTest
{
// Arrange
Rgb input = new(r, g, b);
- ColorConversionOptions options = new() { TargetWhitePoint = KnownIlluminants.D65, RgbWorkingSpace = KnownRgbWorkingSpaces.SRgb };
+ ColorConversionOptions options = new() { TargetWhitePoint = KnownIlluminants.D65, SourceRgbWorkingSpace = KnownRgbWorkingSpaces.SRgb };
ColorProfileConverter converter = new(options);
CieXyz expected = new(x, y, z);
diff --git a/tests/ImageSharp.Tests/ColorProfiles/RgbAndCmykConversionTest.cs b/tests/ImageSharp.Tests/ColorProfiles/RgbAndCmykConversionTest.cs
index 4f4ecb70b..bd35fb775 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/RgbAndCmykConversionTest.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/RgbAndCmykConversionTest.cs
@@ -13,6 +13,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
///
///
///
+[Trait("Color", "Conversion")]
public class RgbAndCmykConversionTest
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0001F);
diff --git a/tests/ImageSharp.Tests/ColorProfiles/RgbAndHslConversionTest.cs b/tests/ImageSharp.Tests/ColorProfiles/RgbAndHslConversionTest.cs
index 0dc95628b..e5874c3d1 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/RgbAndHslConversionTest.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/RgbAndHslConversionTest.cs
@@ -13,6 +13,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
///
///
///
+[Trait("Color", "Conversion")]
public class RgbAndHslConversionTest
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0001f);
diff --git a/tests/ImageSharp.Tests/ColorProfiles/RgbAndHsvConversionTest.cs b/tests/ImageSharp.Tests/ColorProfiles/RgbAndHsvConversionTest.cs
index b89b576b6..4a685abe5 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/RgbAndHsvConversionTest.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/RgbAndHsvConversionTest.cs
@@ -12,6 +12,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
/// Test data generated using:
///
///
+[Trait("Color", "Conversion")]
public class RgbAndHsvConversionTest
{
private static readonly ApproximateColorProfileComparer Comparer = new(.0001f);
diff --git a/tests/ImageSharp.Tests/ColorProfiles/RgbAndYCbCrConversionTest.cs b/tests/ImageSharp.Tests/ColorProfiles/RgbAndYCbCrConversionTest.cs
index 91f7fc08e..ede8226e4 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/RgbAndYCbCrConversionTest.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/RgbAndYCbCrConversionTest.cs
@@ -16,9 +16,9 @@ public class RgbAndYCbCrConversionTest
private static readonly ApproximateColorProfileComparer Comparer = new(.001F);
[Theory]
- [InlineData(255, 128, 128, 1, 1, 1)]
- [InlineData(0, 128, 128, 0, 0, 0)]
- [InlineData(128, 128, 128, 0.502, 0.502, 0.502)]
+ [InlineData(1, .5F, .5F, 1, 1, 1)]
+ [InlineData(0, .5F, .5F, 0, 0, 0)]
+ [InlineData(.5F, .5F, .5F, .5F, .5F, .5F)]
public void Convert_YCbCr_To_Rgb(float y, float cb, float cr, float r, float g, float b)
{
// Arrange
@@ -45,10 +45,9 @@ public class RgbAndYCbCrConversionTest
}
[Theory]
- [InlineData(0, 0, 0, 0, 128, 128)]
- [InlineData(1, 1, 1, 255, 128, 128)]
- [InlineData(0.5, 0.5, 0.5, 127.5, 128, 128)]
- [InlineData(1, 0, 0, 76.245, 84.972, 255)]
+ [InlineData(1, 1, 1, 1, .5F, .5F)]
+ [InlineData(0, 0, 0, 0, .5F, .5F)]
+ [InlineData(.5F, .5F, .5F, .5F, .5F, .5F)]
public void Convert_Rgb_To_YCbCr(float r, float g, float b, float y, float cb, float cr)
{
// Arrange
diff --git a/tests/ImageSharp.Tests/ColorProfiles/RgbAndYccKConversionTests.cs b/tests/ImageSharp.Tests/ColorProfiles/RgbAndYccKConversionTests.cs
new file mode 100644
index 000000000..78f424cc2
--- /dev/null
+++ b/tests/ImageSharp.Tests/ColorProfiles/RgbAndYccKConversionTests.cs
@@ -0,0 +1,80 @@
+// Copyright (c) Six Labors.
+// Licensed under the Six Labors Split License.
+
+using SixLabors.ImageSharp.ColorProfiles;
+
+namespace SixLabors.ImageSharp.Tests.ColorProfiles;
+
+///
+/// Tests - conversions.
+///
+///
+/// Test data generated mathematically
+///
+public class RgbAndYccKConversionTests
+{
+ private static readonly ApproximateColorProfileComparer Comparer = new(.001F);
+
+ [Theory]
+ [InlineData(1, .5F, .5F, 0, 1, 1, 1)]
+ [InlineData(0, .5F, .5F, 1, 0, 0, 0)]
+ [InlineData(.5F, .5F, .5F, 0, .5F, .5F, .5F)]
+ public void Convert_YccK_To_Rgb(float y, float cb, float cr, float k, float r, float g, float b)
+ {
+ // Arrange
+ YccK input = new(y, cb, cr, k);
+ Rgb expected = new(r, g, b);
+ ColorProfileConverter converter = new();
+
+ Span inputSpan = new YccK[5];
+ inputSpan.Fill(input);
+
+ Span actualSpan = new Rgb[5];
+
+ // Act
+ Rgb actual = converter.Convert(input);
+ converter.Convert(inputSpan, actualSpan);
+
+ // Assert
+ Assert.Equal(expected, actual, Comparer);
+
+ for (int i = 0; i < actualSpan.Length; i++)
+ {
+ Assert.Equal(expected, actualSpan[i], Comparer);
+ }
+ }
+
+ [Theory]
+ [InlineData(1, 1, 1, 1, .5F, .5F, 0)]
+ [InlineData(0, 0, 0, 0, .5F, .5F, 1)]
+ [InlineData(.5F, .5F, .5F, 1, .5F, .5F, .5F)]
+ public void Convert_Rgb_To_YccK(float r, float g, float b, float y, float cb, float cr, float k)
+ {
+ // Multiple YccK representations can decode to the same RGB value.
+ // For example, (Y=1.0, Cb=0.5, Cr=0.5, K=0.5) and (Y=0.5, Cb=0.5, Cr=0.5, K=0.0) both yield RGB (0.5, 0.5, 0.5).
+ // This is expected because YccK is not a unique encoding — K modulates RGB after YCbCr decoding.
+ // Round-tripping RGB -> YccK -> RGB is stable, but YccK -> RGB -> YccK is not injective.
+
+ // Arrange
+ Rgb input = new(r, g, b);
+ YccK expected = new(y, cb, cr, k);
+ ColorProfileConverter converter = new();
+
+ Span inputSpan = new Rgb[5];
+ inputSpan.Fill(input);
+
+ Span actualSpan = new YccK[5];
+
+ // Act
+ YccK actual = converter.Convert(input);
+ converter.Convert(inputSpan, actualSpan);
+
+ // Assert
+ Assert.Equal(expected, actual, Comparer);
+
+ for (int i = 0; i < actualSpan.Length; i++)
+ {
+ Assert.Equal(expected, actualSpan[i], Comparer);
+ }
+ }
+}
diff --git a/tests/ImageSharp.Tests/ColorProfiles/RgbTests.cs b/tests/ImageSharp.Tests/ColorProfiles/RgbTests.cs
index 7e4d4ee0e..707b3e2a7 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/RgbTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/RgbTests.cs
@@ -10,6 +10,7 @@ namespace SixLabors.ImageSharp.Tests.ColorProfiles;
///
/// Tests the struct.
///
+[Trait("Color", "Conversion")]
public class RgbTests
{
[Fact]
diff --git a/tests/ImageSharp.Tests/ColorProfiles/StringRepresentationTests.cs b/tests/ImageSharp.Tests/ColorProfiles/StringRepresentationTests.cs
index 770c987db..f61124d8f 100644
--- a/tests/ImageSharp.Tests/ColorProfiles/StringRepresentationTests.cs
+++ b/tests/ImageSharp.Tests/ColorProfiles/StringRepresentationTests.cs
@@ -6,11 +6,13 @@ using SixLabors.ImageSharp.ColorProfiles;
namespace SixLabors.ImageSharp.Tests.ColorProfiles;
+[Trait("Color", "Conversion")]
public class StringRepresentationTests
{
private static readonly Vector3 One = new(1);
private static readonly Vector3 Zero = new(0);
private static readonly Vector3 Random = new(42.4F, 94.5F, 83.4F);
+ private static readonly Vector4 Random4 = new(42.4F, 94.5F, 83.4F, 1);
public static readonly TheoryData