Skip to content

Commit 51ce97f

Browse files
committed
Add unit tests for both converters
1 parent db6f90a commit 51ce97f

File tree

2 files changed

+99
-1
lines changed

2 files changed

+99
-1
lines changed

src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbToYCbCrConverterLut.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ private void ConvertPixelInto(
111111
// float cb = 128F + ((-0.168736F * r) - (0.331264F * g) + (0.5F * b));
112112
cbResult[i] = (this.CbRTable[r] + this.CbGTable[g] + this.CbBTable[b]) >> ScaleBits;
113113

114-
// float cr = 128F + ((0.5F * r) - (0.418688F * g) - (0.081312F * b))
114+
// float cr = 128F + ((0.5F * r) - (0.418688F * g) - (0.081312F * b));
115115
crResult[i] = (this.CbBTable[r] + this.CrGTable[g] + this.CrBTable[b]) >> ScaleBits;
116116
}
117117

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Apache License, Version 2.0.
3+
4+
using System;
5+
using SixLabors.ImageSharp.ColorSpaces;
6+
using SixLabors.ImageSharp.Formats.Jpeg.Components;
7+
using SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder;
8+
using SixLabors.ImageSharp.PixelFormats;
9+
using SixLabors.ImageSharp.Tests.Colorspaces.Conversion;
10+
using Xunit;
11+
using Xunit.Abstractions;
12+
13+
// ReSharper disable InconsistentNaming
14+
namespace SixLabors.ImageSharp.Tests.Formats.Jpg
15+
{
16+
public class RgbToYCbCrConverterTests
17+
{
18+
private const float Epsilon = .5F;
19+
private static readonly ApproximateColorSpaceComparer Comparer = new ApproximateColorSpaceComparer(Epsilon);
20+
21+
public RgbToYCbCrConverterTests(ITestOutputHelper output)
22+
{
23+
this.Output = output;
24+
}
25+
26+
private ITestOutputHelper Output { get; }
27+
28+
[Fact]
29+
public void TestLutConverter()
30+
{
31+
Rgb24[] data = CreateTestData();
32+
var target = RgbToYCbCrConverterLut.Create();
33+
34+
Block8x8F y = default;
35+
Block8x8F cb = default;
36+
Block8x8F cr = default;
37+
38+
target.Convert(data.AsSpan(), ref y, ref cb, ref cr);
39+
40+
Verify(data, ref y, ref cb, ref cr);
41+
}
42+
43+
[Fact]
44+
public void TestVectorizedConverter()
45+
{
46+
if (!RgbToYCbCrConverterVectorized.IsSupported)
47+
{
48+
this.Output.WriteLine("No AVX and/or FMA present, skipping test!");
49+
return;
50+
}
51+
52+
Rgb24[] data = CreateTestData();
53+
54+
// RgbToYCbCrConverterVectorized uses `data` as working memory so we need a copy for verification below
55+
Rgb24[] dataCopy = new Rgb24[data.Length];
56+
data.CopyTo(dataCopy, 0);
57+
58+
Block8x8F y = default;
59+
Block8x8F cb = default;
60+
Block8x8F cr = default;
61+
62+
RgbToYCbCrConverterVectorized.Convert(data.AsSpan(), ref y, ref cb, ref cr);
63+
64+
Verify(dataCopy, ref y, ref cb, ref cr);
65+
}
66+
67+
private static void Verify(ReadOnlySpan<Rgb24> data, ref Block8x8F yResult, ref Block8x8F cbResult, ref Block8x8F crResult)
68+
{
69+
for (int i = 0; i < data.Length; i++)
70+
{
71+
int r = data[i].R;
72+
int g = data[i].G;
73+
int b = data[i].B;
74+
75+
float y = (0.299F * r) + (0.587F * g) + (0.114F * b);
76+
float cb = 128F + ((-0.168736F * r) - (0.331264F * g) + (0.5F * b));
77+
float cr = 128F + ((0.5F * r) - (0.418688F * g) - (0.081312F * b));
78+
79+
Assert.Equal(new YCbCr(y, cb, cr), new YCbCr(yResult[i], cbResult[i], crResult[i]), Comparer);
80+
}
81+
}
82+
83+
private static Rgb24[] CreateTestData()
84+
{
85+
var data = new Rgb24[64];
86+
var r = new Random();
87+
88+
var random = new byte[3];
89+
for (int i = 0; i < data.Length; i++)
90+
{
91+
r.NextBytes(random);
92+
data[i] = new Rgb24(random[0], random[1], random[2]);
93+
}
94+
95+
return data;
96+
}
97+
}
98+
}

0 commit comments

Comments
 (0)