@ -1,274 +1,330 @@
namespace ImageSharp.Benchmarks
namespace ImageSharp.Benchmarks
{
{
using System ;
using System.Buffers ;
using System.Numerics ;
using System.Numerics ;
using System.Runtime.CompilerServices ;
using BenchmarkDotNet.Attributes ;
using BenchmarkDotNet.Attributes ;
public class RgbToYCbCr
using ImageSharp.Formats.Jpg ;
public partial class RgbToYCbCr
{
{
private const int InputColorCount = 6 4 ;
private const int InputByteCount = InputColorCount * 3 ;
private static readonly Vector3 VectorY = new Vector3 ( 0.299F , 0.587F , 0.114F ) ;
private static readonly Vector3 VectorY = new Vector3 ( 0.299F , 0.587F , 0.114F ) ;
private static readonly Vector3 VectorCb = new Vector3 ( - 0.168736F , 0.331264F , 0.5F ) ;
private static readonly Vector3 VectorCb = new Vector3 ( - 0.168736F , 0.331264F , 0.5F ) ;
private static readonly Vector3 VectorCr = new Vector3 ( 0.5F , 0.418688F , 0.081312F ) ;
private static readonly Vector3 VectorCr = new Vector3 ( 0.5F , 0.418688F , 0.081312F ) ;
private static readonly int [ ] Y0Lut =
private static class ScaledCoeffs
{
{
0 , 3 0 6 , 6 1 2 , 9 1 8 , 1 2 2 4 , 1 5 3 0 , 1 8 3 6 , 2 1 4 2 , 2 4 4 8 , 2 7 5 4 , 3 0 6 0 , 3 3 6 6 , 3 6 7 2 , 3 9 7 8 , 4 2 8 4 ,
public static readonly int [ ] Y =
4 5 9 0 , 4 8 9 6 , 5 2 0 2 , 5 5 0 8 , 5 8 1 4 , 6 1 2 0 , 6 4 2 6 , 6 7 3 2 , 7 0 3 8 , 7 3 4 4 , 7 6 5 0 , 7 9 5 6 , 8 2 6 2 , 8 5 6 8 ,
{
8 8 7 4 , 9 1 8 0 , 9 4 8 6 , 9 7 9 2 , 1 0 0 9 8 , 1 0 4 0 4 , 1 0 7 1 0 , 1 1 0 1 6 , 1 1 3 2 2 , 1 1 6 2 8 , 1 1 9 3 4 , 1 2 2 4 0 ,
3 0 6 , 6 0 1 , 1 1 7 , 0 ,
1 2 5 4 6 , 1 2 8 5 2 , 1 3 1 5 8 , 1 3 4 6 4 , 1 3 7 7 0 , 1 4 0 7 6 , 1 4 3 8 2 , 1 4 6 8 8 , 1 4 9 9 4 , 1 5 3 0 0 , 1 5 6 0 6 , 1 5 9 1 2 ,
3 0 6 , 6 0 1 , 1 1 7 , 0 ,
1 6 2 1 8 , 1 6 5 2 4 , 1 6 8 3 0 , 1 7 1 3 6 , 1 7 4 4 2 , 1 7 7 4 8 , 1 8 0 5 4 , 1 8 3 6 0 , 1 8 6 6 6 , 1 8 9 7 2 , 1 9 2 7 8 , 1 9 5 8 4 ,
} ;
1 9 8 9 0 , 2 0 1 9 6 , 2 0 5 0 2 , 2 0 8 0 8 , 2 1 1 1 4 , 2 1 4 2 0 , 2 1 7 2 6 , 2 2 0 3 2 , 2 2 3 3 8 , 2 2 6 4 4 , 2 2 9 5 0 , 2 3 2 5 6 ,
2 3 5 6 2 , 2 3 8 6 8 , 2 4 1 7 4 , 2 4 4 8 0 , 2 4 7 8 6 , 2 5 0 9 2 , 2 5 3 9 8 , 2 5 7 0 4 , 2 6 0 1 0 , 2 6 3 1 6 , 2 6 6 2 2 , 2 6 9 2 8 ,
public static readonly int [ ] Cb =
2 7 2 3 4 , 2 7 5 4 0 , 2 7 8 4 6 , 2 8 1 5 2 , 2 8 4 5 8 , 2 8 7 6 4 , 2 9 0 7 0 , 2 9 3 7 6 , 2 9 6 8 2 , 2 9 9 8 8 , 3 0 2 9 4 , 3 0 6 0 0 ,
{
3 0 9 0 6 , 3 1 2 1 2 , 3 1 5 1 8 , 3 1 8 2 4 , 3 2 1 3 0 , 3 2 4 3 6 , 3 2 7 4 2 , 3 3 0 4 8 , 3 3 3 5 4 , 3 3 6 6 0 , 3 3 9 6 6 , 3 4 2 7 2 ,
- 1 7 2 , 3 3 9 , 5 1 2 , 0 ,
3 4 5 7 8 , 3 4 8 8 4 , 3 5 1 9 0 , 3 5 4 9 6 , 3 5 8 0 2 , 3 6 1 0 8 , 3 6 4 1 4 , 3 6 7 2 0 , 3 7 0 2 6 , 3 7 3 3 2 , 3 7 6 3 8 , 3 7 9 4 4 ,
- 1 7 2 , 3 3 9 , 5 1 2 , 0 ,
3 8 2 5 0 , 3 8 5 5 6 , 3 8 8 6 2 , 3 9 1 6 8 , 3 9 4 7 4 , 3 9 7 8 0 , 4 0 0 8 6 , 4 0 3 9 2 , 4 0 6 9 8 , 4 1 0 0 4 , 4 1 3 1 0 , 4 1 6 1 6 ,
4 1 9 2 2 , 4 2 2 2 8 , 4 2 5 3 4 , 4 2 8 4 0 , 4 3 1 4 6 , 4 3 4 5 2 , 4 3 7 5 8 , 4 4 0 6 4 , 4 4 3 7 0 , 4 4 6 7 6 , 4 4 9 8 2 , 4 5 2 8 8 ,
4 5 5 9 4 , 4 5 9 0 0 , 4 6 2 0 6 , 4 6 5 1 2 , 4 6 8 1 8 , 4 7 1 2 4 , 4 7 4 3 0 , 4 7 7 3 6 , 4 8 0 4 2 , 4 8 3 4 8 , 4 8 6 5 4 , 4 8 9 6 0 ,
4 9 2 6 6 , 4 9 5 7 2 , 4 9 8 7 8 , 5 0 1 8 4 , 5 0 4 9 0 , 5 0 7 9 6 , 5 1 1 0 2 , 5 1 4 0 8 , 5 1 7 1 4 , 5 2 0 2 0 , 5 2 3 2 6 , 5 2 6 3 2 ,
5 2 9 3 8 , 5 3 2 4 4 , 5 3 5 5 0 , 5 3 8 5 6 , 5 4 1 6 2 , 5 4 4 6 8 , 5 4 7 7 4 , 5 5 0 8 0 , 5 5 3 8 6 , 5 5 6 9 2 , 5 5 9 9 8 , 5 6 3 0 4 ,
5 6 6 1 0 , 5 6 9 1 6 , 5 7 2 2 2 , 5 7 5 2 8 , 5 7 8 3 4 , 5 8 1 4 0 , 5 8 4 4 6 , 5 8 7 5 2 , 5 9 0 5 8 , 5 9 3 6 4 , 5 9 6 7 0 , 5 9 9 7 6 ,
6 0 2 8 2 , 6 0 5 8 8 , 6 0 8 9 4 , 6 1 2 0 0 , 6 1 5 0 6 , 6 1 8 1 2 , 6 2 1 1 8 , 6 2 4 2 4 , 6 2 7 3 0 , 6 3 0 3 6 , 6 3 3 4 2 , 6 3 6 4 8 ,
6 3 9 5 4 , 6 4 2 6 0 , 6 4 5 6 6 , 6 4 8 7 2 , 6 5 1 7 8 , 6 5 4 8 4 , 6 5 7 9 0 , 6 6 0 9 6 , 6 6 4 0 2 , 6 6 7 0 8 , 6 7 0 1 4 , 6 7 3 2 0 ,
6 7 6 2 6 , 6 7 9 3 2 , 6 8 2 3 8 , 6 8 5 4 4 , 6 8 8 5 0 , 6 9 1 5 6 , 6 9 4 6 2 , 6 9 7 6 8 , 7 0 0 7 4 , 7 0 3 8 0 , 7 0 6 8 6 , 7 0 9 9 2 ,
7 1 2 9 8 , 7 1 6 0 4 , 7 1 9 1 0 , 7 2 2 1 6 , 7 2 5 2 2 , 7 2 8 2 8 , 7 3 1 3 4 , 7 3 4 4 0 , 7 3 7 4 6 , 7 4 0 5 2 , 7 4 3 5 8 , 7 4 6 6 4 ,
7 4 9 7 0 , 7 5 2 7 6 , 7 5 5 8 2 , 7 5 8 8 8 , 7 6 1 9 4 , 7 6 5 0 0 , 7 6 8 0 6 , 7 7 1 1 2 , 7 7 4 1 8 , 7 7 7 2 4 , 7 8 0 3 0
} ;
} ;
private static readonly int [ ] Y1Lut =
public static readonly int [ ] Cr =
{
{
0 , 6 0 1 , 1 2 0 2 , 1 8 0 3 , 2 4 0 4 , 3 0 0 5 , 3 6 0 6 , 4 2 0 7 , 4 8 0 8 , 5 4 0 9 , 6 0 1 0 , 6 6 1 1 , 7 2 1 2 , 7 8 1 3 , 8 4 1 4 ,
5 1 2 , 4 2 9 , 8 3 , 0 ,
9 0 1 5 , 9 6 1 6 , 1 0 2 1 7 , 1 0 8 1 8 , 1 1 4 1 9 , 1 2 0 2 0 , 1 2 6 2 1 , 1 3 2 2 2 , 1 3 8 2 3 , 1 4 4 2 4 , 1 5 0 2 5 , 1 5 6 2 6 ,
5 1 2 , 4 2 9 , 8 3 , 0 ,
1 6 2 2 7 , 1 6 8 2 8 , 1 7 4 2 9 , 1 8 0 3 0 , 1 8 6 3 1 , 1 9 2 3 2 , 1 9 8 3 3 , 2 0 4 3 4 , 2 1 0 3 5 , 2 1 6 3 6 , 2 2 2 3 7 , 2 2 8 3 8 ,
2 3 4 3 9 , 2 4 0 4 0 , 2 4 6 4 1 , 2 5 2 4 2 , 2 5 8 4 3 , 2 6 4 4 4 , 2 7 0 4 5 , 2 7 6 4 6 , 2 8 2 4 7 , 2 8 8 4 8 , 2 9 4 4 9 , 3 0 0 5 0 ,
3 0 6 5 1 , 3 1 2 5 2 , 3 1 8 5 3 , 3 2 4 5 4 , 3 3 0 5 5 , 3 3 6 5 6 , 3 4 2 5 7 , 3 4 8 5 8 , 3 5 4 5 9 , 3 6 0 6 0 , 3 6 6 6 1 , 3 7 2 6 2 ,
3 7 8 6 3 , 3 8 4 6 4 , 3 9 0 6 5 , 3 9 6 6 6 , 4 0 2 6 7 , 4 0 8 6 8 , 4 1 4 6 9 , 4 2 0 7 0 , 4 2 6 7 1 , 4 3 2 7 2 , 4 3 8 7 3 , 4 4 4 7 4 ,
4 5 0 7 5 , 4 5 6 7 6 , 4 6 2 7 7 , 4 6 8 7 8 , 4 7 4 7 9 , 4 8 0 8 0 , 4 8 6 8 1 , 4 9 2 8 2 , 4 9 8 8 3 , 5 0 4 8 4 , 5 1 0 8 5 , 5 1 6 8 6 ,
5 2 2 8 7 , 5 2 8 8 8 , 5 3 4 8 9 , 5 4 0 9 0 , 5 4 6 9 1 , 5 5 2 9 2 , 5 5 8 9 3 , 5 6 4 9 4 , 5 7 0 9 5 , 5 7 6 9 6 , 5 8 2 9 7 , 5 8 8 9 8 ,
5 9 4 9 9 , 6 0 1 0 0 , 6 0 7 0 1 , 6 1 3 0 2 , 6 1 9 0 3 , 6 2 5 0 4 , 6 3 1 0 5 , 6 3 7 0 6 , 6 4 3 0 7 , 6 4 9 0 8 , 6 5 5 0 9 , 6 6 1 1 0 ,
6 6 7 1 1 , 6 7 3 1 2 , 6 7 9 1 3 , 6 8 5 1 4 , 6 9 1 1 5 , 6 9 7 1 6 , 7 0 3 1 7 , 7 0 9 1 8 , 7 1 5 1 9 , 7 2 1 2 0 , 7 2 7 2 1 , 7 3 3 2 2 ,
7 3 9 2 3 , 7 4 5 2 4 , 7 5 1 2 5 , 7 5 7 2 6 , 7 6 3 2 7 , 7 6 9 2 8 , 7 7 5 2 9 , 7 8 1 3 0 , 7 8 7 3 1 , 7 9 3 3 2 , 7 9 9 3 3 , 8 0 5 3 4 ,
8 1 1 3 5 , 8 1 7 3 6 , 8 2 3 3 7 , 8 2 9 3 8 , 8 3 5 3 9 , 8 4 1 4 0 , 8 4 7 4 1 , 8 5 3 4 2 , 8 5 9 4 3 , 8 6 5 4 4 , 8 7 1 4 5 , 8 7 7 4 6 ,
8 8 3 4 7 , 8 8 9 4 8 , 8 9 5 4 9 , 9 0 1 5 0 , 9 0 7 5 1 , 9 1 3 5 2 , 9 1 9 5 3 , 9 2 5 5 4 , 9 3 1 5 5 , 9 3 7 5 6 , 9 4 3 5 7 , 9 4 9 5 8 ,
9 5 5 5 9 , 9 6 1 6 0 , 9 6 7 6 1 , 9 7 3 6 2 , 9 7 9 6 3 , 9 8 5 6 4 , 9 9 1 6 5 , 9 9 7 6 6 , 1 0 0 3 6 7 , 1 0 0 9 6 8 , 1 0 1 5 6 9 ,
1 0 2 1 7 0 , 1 0 2 7 7 1 , 1 0 3 3 7 2 , 1 0 3 9 7 3 , 1 0 4 5 7 4 , 1 0 5 1 7 5 , 1 0 5 7 7 6 , 1 0 6 3 7 7 , 1 0 6 9 7 8 , 1 0 7 5 7 9 ,
1 0 8 1 8 0 , 1 0 8 7 8 1 , 1 0 9 3 8 2 , 1 0 9 9 8 3 , 1 1 0 5 8 4 , 1 1 1 1 8 5 , 1 1 1 7 8 6 , 1 1 2 3 8 7 , 1 1 2 9 8 8 , 1 1 3 5 8 9 ,
1 1 4 1 9 0 , 1 1 4 7 9 1 , 1 1 5 3 9 2 , 1 1 5 9 9 3 , 1 1 6 5 9 4 , 1 1 7 1 9 5 , 1 1 7 7 9 6 , 1 1 8 3 9 7 , 1 1 8 9 9 8 , 1 1 9 5 9 9 ,
1 2 0 2 0 0 , 1 2 0 8 0 1 , 1 2 1 4 0 2 , 1 2 2 0 0 3 , 1 2 2 6 0 4 , 1 2 3 2 0 5 , 1 2 3 8 0 6 , 1 2 4 4 0 7 , 1 2 5 0 0 8 , 1 2 5 6 0 9 ,
1 2 6 2 1 0 , 1 2 6 8 1 1 , 1 2 7 4 1 2 , 1 2 8 0 1 3 , 1 2 8 6 1 4 , 1 2 9 2 1 5 , 1 2 9 8 1 6 , 1 3 0 4 1 7 , 1 3 1 0 1 8 , 1 3 1 6 1 9 ,
1 3 2 2 2 0 , 1 3 2 8 2 1 , 1 3 3 4 2 2 , 1 3 4 0 2 3 , 1 3 4 6 2 4 , 1 3 5 2 2 5 , 1 3 5 8 2 6 , 1 3 6 4 2 7 , 1 3 7 0 2 8 , 1 3 7 6 2 9 ,
1 3 8 2 3 0 , 1 3 8 8 3 1 , 1 3 9 4 3 2 , 1 4 0 0 3 3 , 1 4 0 6 3 4 , 1 4 1 2 3 5 , 1 4 1 8 3 6 , 1 4 2 4 3 7 , 1 4 3 0 3 8 , 1 4 3 6 3 9 ,
1 4 4 2 4 0 , 1 4 4 8 4 1 , 1 4 5 4 4 2 , 1 4 6 0 4 3 , 1 4 6 6 4 4 , 1 4 7 2 4 5 , 1 4 7 8 4 6 , 1 4 8 4 4 7 , 1 4 9 0 4 8 , 1 4 9 6 4 9 ,
1 5 0 2 5 0 , 1 5 0 8 5 1 , 1 5 1 4 5 2 , 1 5 2 0 5 3 , 1 5 2 6 5 4 , 1 5 3 2 5 5
} ;
} ;
private static readonly int [ ] Y2Lut =
public static class SelectLeft
{
{
0 , 1 1 7 , 2 3 4 , 3 5 1 , 4 6 8 , 5 8 5 , 7 0 2 , 8 1 9 , 9 3 6 , 1 0 5 3 , 1 1 7 0 , 1 2 8 7 , 1 4 0 4 , 1 5 2 1 , 1 6 3 8 , 1 7 5 5 ,
public static readonly int [ ] Y =
1 8 7 2 , 1 9 8 9 , 2 1 0 6 , 2 2 2 3 , 2 3 4 0 , 2 4 5 7 , 2 5 7 4 , 2 6 9 1 , 2 8 0 8 , 2 9 2 5 , 3 0 4 2 , 3 1 5 9 , 3 2 7 6 , 3 3 9 3 ,
{
3 5 1 0 , 3 6 2 7 , 3 7 4 4 , 3 8 6 1 , 3 9 7 8 , 4 0 9 5 , 4 2 1 2 , 4 3 2 9 , 4 4 4 6 , 4 5 6 3 , 4 6 8 0 , 4 7 9 7 , 4 9 1 4 , 5 0 3 1 ,
1 , 1 , 1 , 0 ,
5 1 4 8 , 5 2 6 5 , 5 3 8 2 , 5 4 9 9 , 5 6 1 6 , 5 7 3 3 , 5 8 5 0 , 5 9 6 7 , 6 0 8 4 , 6 2 0 1 , 6 3 1 8 , 6 4 3 5 , 6 5 5 2 , 6 6 6 9 ,
0 , 0 , 0 , 0 ,
6 7 8 6 , 6 9 0 3 , 7 0 2 0 , 7 1 3 7 , 7 2 5 4 , 7 3 7 1 , 7 4 8 8 , 7 6 0 5 , 7 7 2 2 , 7 8 3 9 , 7 9 5 6 , 8 0 7 3 , 8 1 9 0 , 8 3 0 7 ,
8 4 2 4 , 8 5 4 1 , 8 6 5 8 , 8 7 7 5 , 8 8 9 2 , 9 0 0 9 , 9 1 2 6 , 9 2 4 3 , 9 3 6 0 , 9 4 7 7 , 9 5 9 4 , 9 7 1 1 , 9 8 2 8 , 9 9 4 5 ,
1 0 0 6 2 , 1 0 1 7 9 , 1 0 2 9 6 , 1 0 4 1 3 , 1 0 5 3 0 , 1 0 6 4 7 , 1 0 7 6 4 , 1 0 8 8 1 , 1 0 9 9 8 , 1 1 1 1 5 , 1 1 2 3 2 , 1 1 3 4 9 ,
1 1 4 6 6 , 1 1 5 8 3 , 1 1 7 0 0 , 1 1 8 1 7 , 1 1 9 3 4 , 1 2 0 5 1 , 1 2 1 6 8 , 1 2 2 8 5 , 1 2 4 0 2 , 1 2 5 1 9 , 1 2 6 3 6 , 1 2 7 5 3 ,
1 2 8 7 0 , 1 2 9 8 7 , 1 3 1 0 4 , 1 3 2 2 1 , 1 3 3 3 8 , 1 3 4 5 5 , 1 3 5 7 2 , 1 3 6 8 9 , 1 3 8 0 6 , 1 3 9 2 3 , 1 4 0 4 0 , 1 4 1 5 7 ,
1 4 2 7 4 , 1 4 3 9 1 , 1 4 5 0 8 , 1 4 6 2 5 , 1 4 7 4 2 , 1 4 8 5 9 , 1 4 9 7 6 , 1 5 0 9 3 , 1 5 2 1 0 , 1 5 3 2 7 , 1 5 4 4 4 , 1 5 5 6 1 ,
1 5 6 7 8 , 1 5 7 9 5 , 1 5 9 1 2 , 1 6 0 2 9 , 1 6 1 4 6 , 1 6 2 6 3 , 1 6 3 8 0 , 1 6 4 9 7 , 1 6 6 1 4 , 1 6 7 3 1 , 1 6 8 4 8 , 1 6 9 6 5 ,
1 7 0 8 2 , 1 7 1 9 9 , 1 7 3 1 6 , 1 7 4 3 3 , 1 7 5 5 0 , 1 7 6 6 7 , 1 7 7 8 4 , 1 7 9 0 1 , 1 8 0 1 8 , 1 8 1 3 5 , 1 8 2 5 2 , 1 8 3 6 9 ,
1 8 4 8 6 , 1 8 6 0 3 , 1 8 7 2 0 , 1 8 8 3 7 , 1 8 9 5 4 , 1 9 0 7 1 , 1 9 1 8 8 , 1 9 3 0 5 , 1 9 4 2 2 , 1 9 5 3 9 , 1 9 6 5 6 , 1 9 7 7 3 ,
1 9 8 9 0 , 2 0 0 0 7 , 2 0 1 2 4 , 2 0 2 4 1 , 2 0 3 5 8 , 2 0 4 7 5 , 2 0 5 9 2 , 2 0 7 0 9 , 2 0 8 2 6 , 2 0 9 4 3 , 2 1 0 6 0 , 2 1 1 7 7 ,
2 1 2 9 4 , 2 1 4 1 1 , 2 1 5 2 8 , 2 1 6 4 5 , 2 1 7 6 2 , 2 1 8 7 9 , 2 1 9 9 6 , 2 2 1 1 3 , 2 2 2 3 0 , 2 2 3 4 7 , 2 2 4 6 4 , 2 2 5 8 1 ,
2 2 6 9 8 , 2 2 8 1 5 , 2 2 9 3 2 , 2 3 0 4 9 , 2 3 1 6 6 , 2 3 2 8 3 , 2 3 4 0 0 , 2 3 5 1 7 , 2 3 6 3 4 , 2 3 7 5 1 , 2 3 8 6 8 , 2 3 9 8 5 ,
2 4 1 0 2 , 2 4 2 1 9 , 2 4 3 3 6 , 2 4 4 5 3 , 2 4 5 7 0 , 2 4 6 8 7 , 2 4 8 0 4 , 2 4 9 2 1 , 2 5 0 3 8 , 2 5 1 5 5 , 2 5 2 7 2 , 2 5 3 8 9 ,
2 5 5 0 6 , 2 5 6 2 3 , 2 5 7 4 0 , 2 5 8 5 7 , 2 5 9 7 4 , 2 6 0 9 1 , 2 6 2 0 8 , 2 6 3 2 5 , 2 6 4 4 2 , 2 6 5 5 9 , 2 6 6 7 6 , 2 6 7 9 3 ,
2 6 9 1 0 , 2 7 0 2 7 , 2 7 1 4 4 , 2 7 2 6 1 , 2 7 3 7 8 , 2 7 4 9 5 , 2 7 6 1 2 , 2 7 7 2 9 , 2 7 8 4 6 , 2 7 9 6 3 , 2 8 0 8 0 , 2 8 1 9 7 ,
2 8 3 1 4 , 2 8 4 3 1 , 2 8 5 4 8 , 2 8 6 6 5 , 2 8 7 8 2 , 2 8 8 9 9 , 2 9 0 1 6 , 2 9 1 3 3 , 2 9 2 5 0 , 2 9 3 6 7 , 2 9 4 8 4 , 2 9 6 0 1 ,
2 9 7 1 8 , 2 9 8 3 5
} ;
} ;
private static readonly int [ ] Cb0Lut =
public static readonly int [ ] Cb =
{
{
0 , - 1 7 2 , - 3 4 4 , - 5 1 6 , - 6 8 8 , - 8 6 0 , - 1 0 3 2 , - 1 2 0 4 , - 1 3 7 6 , - 1 5 4 8 , - 1 7 2 0 , - 1 8 9 2 ,
1 , - 1 , 1 , 0 ,
- 2 0 6 4 , - 2 2 3 6 , - 2 4 0 8 , - 2 5 8 0 , - 2 7 5 2 , - 2 9 2 4 , - 3 0 9 6 , - 3 2 6 8 , - 3 4 4 0 , - 3 6 1 2 ,
0 , 0 , 0 , 0 ,
- 3 7 8 4 , - 3 9 5 6 , - 4 1 2 8 , - 4 3 0 0 , - 4 4 7 2 , - 4 6 4 4 , - 4 8 1 6 , - 4 9 8 8 , - 5 1 6 0 , - 5 3 3 2 ,
- 5 5 0 4 , - 5 6 7 6 , - 5 8 4 8 , - 6 0 2 0 , - 6 1 9 2 , - 6 3 6 4 , - 6 5 3 6 , - 6 7 0 8 , - 6 8 8 0 , - 7 0 5 2 ,
- 7 2 2 4 , - 7 3 9 6 , - 7 5 6 8 , - 7 7 4 0 , - 7 9 1 2 , - 8 0 8 4 , - 8 2 5 6 , - 8 4 2 8 , - 8 6 0 0 , - 8 7 7 2 ,
- 8 9 4 4 , - 9 1 1 6 , - 9 2 8 8 , - 9 4 6 0 , - 9 6 3 2 , - 9 8 0 4 , - 9 9 7 6 , - 1 0 1 4 8 , - 1 0 3 2 0 , - 1 0 4 9 2 ,
- 1 0 6 6 4 , - 1 0 8 3 6 , - 1 1 0 0 8 , - 1 1 1 8 0 , - 1 1 3 5 2 , - 1 1 5 2 4 , - 1 1 6 9 6 , - 1 1 8 6 8 , - 1 2 0 4 0 ,
- 1 2 2 1 2 , - 1 2 3 8 4 , - 1 2 5 5 6 , - 1 2 7 2 8 , - 1 2 9 0 0 , - 1 3 0 7 2 , - 1 3 2 4 4 , - 1 3 4 1 6 , - 1 3 5 8 8 ,
- 1 3 7 6 0 , - 1 3 9 3 2 , - 1 4 1 0 4 , - 1 4 2 7 6 , - 1 4 4 4 8 , - 1 4 6 2 0 , - 1 4 7 9 2 , - 1 4 9 6 4 , - 1 5 1 3 6 ,
- 1 5 3 0 8 , - 1 5 4 8 0 , - 1 5 6 5 2 , - 1 5 8 2 4 , - 1 5 9 9 6 , - 1 6 1 6 8 , - 1 6 3 4 0 , - 1 6 5 1 2 , - 1 6 6 8 4 ,
- 1 6 8 5 6 , - 1 7 0 2 8 , - 1 7 2 0 0 , - 1 7 3 7 2 , - 1 7 5 4 4 , - 1 7 7 1 6 , - 1 7 8 8 8 , - 1 8 0 6 0 , - 1 8 2 3 2 ,
- 1 8 4 0 4 , - 1 8 5 7 6 , - 1 8 7 4 8 , - 1 8 9 2 0 , - 1 9 0 9 2 , - 1 9 2 6 4 , - 1 9 4 3 6 , - 1 9 6 0 8 , - 1 9 7 8 0 ,
- 1 9 9 5 2 , - 2 0 1 2 4 , - 2 0 2 9 6 , - 2 0 4 6 8 , - 2 0 6 4 0 , - 2 0 8 1 2 , - 2 0 9 8 4 , - 2 1 1 5 6 , - 2 1 3 2 8 ,
- 2 1 5 0 0 , - 2 1 6 7 2 , - 2 1 8 4 4 , - 2 2 0 1 6 , - 2 2 1 8 8 , - 2 2 3 6 0 , - 2 2 5 3 2 , - 2 2 7 0 4 , - 2 2 8 7 6 ,
- 2 3 0 4 8 , - 2 3 2 2 0 , - 2 3 3 9 2 , - 2 3 5 6 4 , - 2 3 7 3 6 , - 2 3 9 0 8 , - 2 4 0 8 0 , - 2 4 2 5 2 , - 2 4 4 2 4 ,
- 2 4 5 9 6 , - 2 4 7 6 8 , - 2 4 9 4 0 , - 2 5 1 1 2 , - 2 5 2 8 4 , - 2 5 4 5 6 , - 2 5 6 2 8 , - 2 5 8 0 0 , - 2 5 9 7 2 ,
- 2 6 1 4 4 , - 2 6 3 1 6 , - 2 6 4 8 8 , - 2 6 6 6 0 , - 2 6 8 3 2 , - 2 7 0 0 4 , - 2 7 1 7 6 , - 2 7 3 4 8 , - 2 7 5 2 0 ,
- 2 7 6 9 2 , - 2 7 8 6 4 , - 2 8 0 3 6 , - 2 8 2 0 8 , - 2 8 3 8 0 , - 2 8 5 5 2 , - 2 8 7 2 4 , - 2 8 8 9 6 , - 2 9 0 6 8 ,
- 2 9 2 4 0 , - 2 9 4 1 2 , - 2 9 5 8 4 , - 2 9 7 5 6 , - 2 9 9 2 8 , - 3 0 1 0 0 , - 3 0 2 7 2 , - 3 0 4 4 4 , - 3 0 6 1 6 ,
- 3 0 7 8 8 , - 3 0 9 6 0 , - 3 1 1 3 2 , - 3 1 3 0 4 , - 3 1 4 7 6 , - 3 1 6 4 8 , - 3 1 8 2 0 , - 3 1 9 9 2 , - 3 2 1 6 4 ,
- 3 2 3 3 6 , - 3 2 5 0 8 , - 3 2 6 8 0 , - 3 2 8 5 2 , - 3 3 0 2 4 , - 3 3 1 9 6 , - 3 3 3 6 8 , - 3 3 5 4 0 , - 3 3 7 1 2 ,
- 3 3 8 8 4 , - 3 4 0 5 6 , - 3 4 2 2 8 , - 3 4 4 0 0 , - 3 4 5 7 2 , - 3 4 7 4 4 , - 3 4 9 1 6 , - 3 5 0 8 8 , - 3 5 2 6 0 ,
- 3 5 4 3 2 , - 3 5 6 0 4 , - 3 5 7 7 6 , - 3 5 9 4 8 , - 3 6 1 2 0 , - 3 6 2 9 2 , - 3 6 4 6 4 , - 3 6 6 3 6 , - 3 6 8 0 8 ,
- 3 6 9 8 0 , - 3 7 1 5 2 , - 3 7 3 2 4 , - 3 7 4 9 6 , - 3 7 6 6 8 , - 3 7 8 4 0 , - 3 8 0 1 2 , - 3 8 1 8 4 , - 3 8 3 5 6 ,
- 3 8 5 2 8 , - 3 8 7 0 0 , - 3 8 8 7 2 , - 3 9 0 4 4 , - 3 9 2 1 6 , - 3 9 3 8 8 , - 3 9 5 6 0 , - 3 9 7 3 2 , - 3 9 9 0 4 ,
- 4 0 0 7 6 , - 4 0 2 4 8 , - 4 0 4 2 0 , - 4 0 5 9 2 , - 4 0 7 6 4 , - 4 0 9 3 6 , - 4 1 1 0 8 , - 4 1 2 8 0 , - 4 1 4 5 2 ,
- 4 1 6 2 4 , - 4 1 7 9 6 , - 4 1 9 6 8 , - 4 2 1 4 0 , - 4 2 3 1 2 , - 4 2 4 8 4 , - 4 2 6 5 6 , - 4 2 8 2 8 , - 4 3 0 0 0 ,
- 4 3 1 7 2 , - 4 3 3 4 4 , - 4 3 5 1 6 , - 4 3 6 8 8 , - 4 3 8 6 0
} ;
} ;
private static readonly int [ ] Cb1Lut =
public static readonly int [ ] Cr =
{
{
0 , 3 3 9 , 6 7 8 , 1 0 1 7 , 1 3 5 6 , 1 6 9 5 , 2 0 3 4 , 2 3 7 3 , 2 7 1 2 , 3 0 5 1 , 3 3 9 0 , 3 7 2 9 , 4 0 6 8 ,
1 , - 1 , - 1 , 0 ,
4 4 0 7 , 4 7 4 6 , 5 0 8 5 , 5 4 2 4 , 5 7 6 3 , 6 1 0 2 , 6 4 4 1 , 6 7 8 0 , 7 1 1 9 , 7 4 5 8 , 7 7 9 7 , 8 1 3 6 ,
0 , 0 , 0 , 0 ,
8 4 7 5 , 8 8 1 4 , 9 1 5 3 , 9 4 9 2 , 9 8 3 1 , 1 0 1 7 0 , 1 0 5 0 9 , 1 0 8 4 8 , 1 1 1 8 7 , 1 1 5 2 6 , 1 1 8 6 5 ,
1 2 2 0 4 , 1 2 5 4 3 , 1 2 8 8 2 , 1 3 2 2 1 , 1 3 5 6 0 , 1 3 8 9 9 , 1 4 2 3 8 , 1 4 5 7 7 , 1 4 9 1 6 , 1 5 2 5 5 ,
1 5 5 9 4 , 1 5 9 3 3 , 1 6 2 7 2 , 1 6 6 1 1 , 1 6 9 5 0 , 1 7 2 8 9 , 1 7 6 2 8 , 1 7 9 6 7 , 1 8 3 0 6 , 1 8 6 4 5 ,
1 8 9 8 4 , 1 9 3 2 3 , 1 9 6 6 2 , 2 0 0 0 1 , 2 0 3 4 0 , 2 0 6 7 9 , 2 1 0 1 8 , 2 1 3 5 7 , 2 1 6 9 6 , 2 2 0 3 5 ,
2 2 3 7 4 , 2 2 7 1 3 , 2 3 0 5 2 , 2 3 3 9 1 , 2 3 7 3 0 , 2 4 0 6 9 , 2 4 4 0 8 , 2 4 7 4 7 , 2 5 0 8 6 , 2 5 4 2 5 ,
2 5 7 6 4 , 2 6 1 0 3 , 2 6 4 4 2 , 2 6 7 8 1 , 2 7 1 2 0 , 2 7 4 5 9 , 2 7 7 9 8 , 2 8 1 3 7 , 2 8 4 7 6 , 2 8 8 1 5 ,
2 9 1 5 4 , 2 9 4 9 3 , 2 9 8 3 2 , 3 0 1 7 1 , 3 0 5 1 0 , 3 0 8 4 9 , 3 1 1 8 8 , 3 1 5 2 7 , 3 1 8 6 6 , 3 2 2 0 5 ,
3 2 5 4 4 , 3 2 8 8 3 , 3 3 2 2 2 , 3 3 5 6 1 , 3 3 9 0 0 , 3 4 2 3 9 , 3 4 5 7 8 , 3 4 9 1 7 , 3 5 2 5 6 , 3 5 5 9 5 ,
3 5 9 3 4 , 3 6 2 7 3 , 3 6 6 1 2 , 3 6 9 5 1 , 3 7 2 9 0 , 3 7 6 2 9 , 3 7 9 6 8 , 3 8 3 0 7 , 3 8 6 4 6 , 3 8 9 8 5 ,
3 9 3 2 4 , 3 9 6 6 3 , 4 0 0 0 2 , 4 0 3 4 1 , 4 0 6 8 0 , 4 1 0 1 9 , 4 1 3 5 8 , 4 1 6 9 7 , 4 2 0 3 6 , 4 2 3 7 5 ,
4 2 7 1 4 , 4 3 0 5 3 , 4 3 3 9 2 , 4 3 7 3 1 , 4 4 0 7 0 , 4 4 4 0 9 , 4 4 7 4 8 , 4 5 0 8 7 , 4 5 4 2 6 , 4 5 7 6 5 ,
4 6 1 0 4 , 4 6 4 4 3 , 4 6 7 8 2 , 4 7 1 2 1 , 4 7 4 6 0 , 4 7 7 9 9 , 4 8 1 3 8 , 4 8 4 7 7 , 4 8 8 1 6 , 4 9 1 5 5 ,
4 9 4 9 4 , 4 9 8 3 3 , 5 0 1 7 2 , 5 0 5 1 1 , 5 0 8 5 0 , 5 1 1 8 9 , 5 1 5 2 8 , 5 1 8 6 7 , 5 2 2 0 6 , 5 2 5 4 5 ,
5 2 8 8 4 , 5 3 2 2 3 , 5 3 5 6 2 , 5 3 9 0 1 , 5 4 2 4 0 , 5 4 5 7 9 , 5 4 9 1 8 , 5 5 2 5 7 , 5 5 5 9 6 , 5 5 9 3 5 ,
5 6 2 7 4 , 5 6 6 1 3 , 5 6 9 5 2 , 5 7 2 9 1 , 5 7 6 3 0 , 5 7 9 6 9 , 5 8 3 0 8 , 5 8 6 4 7 , 5 8 9 8 6 , 5 9 3 2 5 ,
5 9 6 6 4 , 6 0 0 0 3 , 6 0 3 4 2 , 6 0 6 8 1 , 6 1 0 2 0 , 6 1 3 5 9 , 6 1 6 9 8 , 6 2 0 3 7 , 6 2 3 7 6 , 6 2 7 1 5 ,
6 3 0 5 4 , 6 3 3 9 3 , 6 3 7 3 2 , 6 4 0 7 1 , 6 4 4 1 0 , 6 4 7 4 9 , 6 5 0 8 8 , 6 5 4 2 7 , 6 5 7 6 6 , 6 6 1 0 5 ,
6 6 4 4 4 , 6 6 7 8 3 , 6 7 1 2 2 , 6 7 4 6 1 , 6 7 8 0 0 , 6 8 1 3 9 , 6 8 4 7 8 , 6 8 8 1 7 , 6 9 1 5 6 , 6 9 4 9 5 ,
6 9 8 3 4 , 7 0 1 7 3 , 7 0 5 1 2 , 7 0 8 5 1 , 7 1 1 9 0 , 7 1 5 2 9 , 7 1 8 6 8 , 7 2 2 0 7 , 7 2 5 4 6 , 7 2 8 8 5 ,
7 3 2 2 4 , 7 3 5 6 3 , 7 3 9 0 2 , 7 4 2 4 1 , 7 4 5 8 0 , 7 4 9 1 9 , 7 5 2 5 8 , 7 5 5 9 7 , 7 5 9 3 6 , 7 6 2 7 5 ,
7 6 6 1 4 , 7 6 9 5 3 , 7 7 2 9 2 , 7 7 6 3 1 , 7 7 9 7 0 , 7 8 3 0 9 , 7 8 6 4 8 , 7 8 9 8 7 , 7 9 3 2 6 , 7 9 6 6 5 ,
8 0 0 0 4 , 8 0 3 4 3 , 8 0 6 8 2 , 8 1 0 2 1 , 8 1 3 6 0 , 8 1 6 9 9 , 8 2 0 3 8 , 8 2 3 7 7 , 8 2 7 1 6 , 8 3 0 5 5 ,
8 3 3 9 4 , 8 3 7 3 3 , 8 4 0 7 2 , 8 4 4 1 1 , 8 4 7 5 0 , 8 5 0 8 9 , 8 5 4 2 8 , 8 5 7 6 7 , 8 6 1 0 6 , 8 6 4 4 5
} ;
} ;
}
private static readonly int [ ] Cb2Cr0Lut =
public static class SelectRight
{
{
0 , 5 1 2 , 1 0 2 4 , 1 5 3 6 , 2 0 4 8 , 2 5 6 0 , 3 0 7 2 , 3 5 8 4 , 4 0 9 6 , 4 6 0 8 , 5 1 2 0 , 5 6 3 2 , 6 1 4 4 ,
public static readonly int [ ] Y =
6 6 5 6 , 7 1 6 8 , 7 6 8 0 , 8 1 9 2 , 8 7 0 4 , 9 2 1 6 , 9 7 2 8 , 1 0 2 4 0 , 1 0 7 5 2 , 1 1 2 6 4 , 1 1 7 7 6 ,
{
1 2 2 8 8 , 1 2 8 0 0 , 1 3 3 1 2 , 1 3 8 2 4 , 1 4 3 3 6 , 1 4 8 4 8 , 1 5 3 6 0 , 1 5 8 7 2 , 1 6 3 8 4 , 1 6 8 9 6 ,
0 , 0 , 0 , 0 ,
1 7 4 0 8 , 1 7 9 2 0 , 1 8 4 3 2 , 1 8 9 4 4 , 1 9 4 5 6 , 1 9 9 6 8 , 2 0 4 8 0 , 2 0 9 9 2 , 2 1 5 0 4 , 2 2 0 1 6 ,
1 , 1 , 1 , 0 ,
2 2 5 2 8 , 2 3 0 4 0 , 2 3 5 5 2 , 2 4 0 6 4 , 2 4 5 7 6 , 2 5 0 8 8 , 2 5 6 0 0 , 2 6 1 1 2 , 2 6 6 2 4 , 2 7 1 3 6 ,
2 7 6 4 8 , 2 8 1 6 0 , 2 8 6 7 2 , 2 9 1 8 4 , 2 9 6 9 6 , 3 0 2 0 8 , 3 0 7 2 0 , 3 1 2 3 2 , 3 1 7 4 4 , 3 2 2 5 6 ,
3 2 7 6 8 , 3 3 2 8 0 , 3 3 7 9 2 , 3 4 3 0 4 , 3 4 8 1 6 , 3 5 3 2 8 , 3 5 8 4 0 , 3 6 3 5 2 , 3 6 8 6 4 , 3 7 3 7 6 ,
3 7 8 8 8 , 3 8 4 0 0 , 3 8 9 1 2 , 3 9 4 2 4 , 3 9 9 3 6 , 4 0 4 4 8 , 4 0 9 6 0 , 4 1 4 7 2 , 4 1 9 8 4 , 4 2 4 9 6 ,
4 3 0 0 8 , 4 3 5 2 0 , 4 4 0 3 2 , 4 4 5 4 4 , 4 5 0 5 6 , 4 5 5 6 8 , 4 6 0 8 0 , 4 6 5 9 2 , 4 7 1 0 4 , 4 7 6 1 6 ,
4 8 1 2 8 , 4 8 6 4 0 , 4 9 1 5 2 , 4 9 6 6 4 , 5 0 1 7 6 , 5 0 6 8 8 , 5 1 2 0 0 , 5 1 7 1 2 , 5 2 2 2 4 , 5 2 7 3 6 ,
5 3 2 4 8 , 5 3 7 6 0 , 5 4 2 7 2 , 5 4 7 8 4 , 5 5 2 9 6 , 5 5 8 0 8 , 5 6 3 2 0 , 5 6 8 3 2 , 5 7 3 4 4 , 5 7 8 5 6 ,
5 8 3 6 8 , 5 8 8 8 0 , 5 9 3 9 2 , 5 9 9 0 4 , 6 0 4 1 6 , 6 0 9 2 8 , 6 1 4 4 0 , 6 1 9 5 2 , 6 2 4 6 4 , 6 2 9 7 6 ,
6 3 4 8 8 , 6 4 0 0 0 , 6 4 5 1 2 , 6 5 0 2 4 , 6 5 5 3 6 , 6 6 0 4 8 , 6 6 5 6 0 , 6 7 0 7 2 , 6 7 5 8 4 , 6 8 0 9 6 ,
6 8 6 0 8 , 6 9 1 2 0 , 6 9 6 3 2 , 7 0 1 4 4 , 7 0 6 5 6 , 7 1 1 6 8 , 7 1 6 8 0 , 7 2 1 9 2 , 7 2 7 0 4 , 7 3 2 1 6 ,
7 3 7 2 8 , 7 4 2 4 0 , 7 4 7 5 2 , 7 5 2 6 4 , 7 5 7 7 6 , 7 6 2 8 8 , 7 6 8 0 0 , 7 7 3 1 2 , 7 7 8 2 4 , 7 8 3 3 6 ,
7 8 8 4 8 , 7 9 3 6 0 , 7 9 8 7 2 , 8 0 3 8 4 , 8 0 8 9 6 , 8 1 4 0 8 , 8 1 9 2 0 , 8 2 4 3 2 , 8 2 9 4 4 , 8 3 4 5 6 ,
8 3 9 6 8 , 8 4 4 8 0 , 8 4 9 9 2 , 8 5 5 0 4 , 8 6 0 1 6 , 8 6 5 2 8 , 8 7 0 4 0 , 8 7 5 5 2 , 8 8 0 6 4 , 8 8 5 7 6 ,
8 9 0 8 8 , 8 9 6 0 0 , 9 0 1 1 2 , 9 0 6 2 4 , 9 1 1 3 6 , 9 1 6 4 8 , 9 2 1 6 0 , 9 2 6 7 2 , 9 3 1 8 4 , 9 3 6 9 6 ,
9 4 2 0 8 , 9 4 7 2 0 , 9 5 2 3 2 , 9 5 7 4 4 , 9 6 2 5 6 , 9 6 7 6 8 , 9 7 2 8 0 , 9 7 7 9 2 , 9 8 3 0 4 , 9 8 8 1 6 ,
9 9 3 2 8 , 9 9 8 4 0 , 1 0 0 3 5 2 , 1 0 0 8 6 4 , 1 0 1 3 7 6 , 1 0 1 8 8 8 , 1 0 2 4 0 0 , 1 0 2 9 1 2 , 1 0 3 4 2 4 ,
1 0 3 9 3 6 , 1 0 4 4 4 8 , 1 0 4 9 6 0 , 1 0 5 4 7 2 , 1 0 5 9 8 4 , 1 0 6 4 9 6 , 1 0 7 0 0 8 , 1 0 7 5 2 0 , 1 0 8 0 3 2 ,
1 0 8 5 4 4 , 1 0 9 0 5 6 , 1 0 9 5 6 8 , 1 1 0 0 8 0 , 1 1 0 5 9 2 , 1 1 1 1 0 4 , 1 1 1 6 1 6 , 1 1 2 1 2 8 , 1 1 2 6 4 0 ,
1 1 3 1 5 2 , 1 1 3 6 6 4 , 1 1 4 1 7 6 , 1 1 4 6 8 8 , 1 1 5 2 0 0 , 1 1 5 7 1 2 , 1 1 6 2 2 4 , 1 1 6 7 3 6 , 1 1 7 2 4 8 ,
1 1 7 7 6 0 , 1 1 8 2 7 2 , 1 1 8 7 8 4 , 1 1 9 2 9 6 , 1 1 9 8 0 8 , 1 2 0 3 2 0 , 1 2 0 8 3 2 , 1 2 1 3 4 4 , 1 2 1 8 5 6 ,
1 2 2 3 6 8 , 1 2 2 8 8 0 , 1 2 3 3 9 2 , 1 2 3 9 0 4 , 1 2 4 4 1 6 , 1 2 4 9 2 8 , 1 2 5 4 4 0 , 1 2 5 9 5 2 , 1 2 6 4 6 4 ,
1 2 6 9 7 6 , 1 2 7 4 8 8 , 1 2 8 0 0 0 , 1 2 8 5 1 2 , 1 2 9 0 2 4 , 1 2 9 5 3 6 , 1 3 0 0 4 8 , 1 3 0 5 6 0
} ;
} ;
private static readonly int [ ] Cr1Lut =
public static readonly int [ ] Cb =
{
{
0 , 4 2 9 , 8 5 8 , 1 2 8 7 , 1 7 1 6 , 2 1 4 5 , 2 5 7 4 , 3 0 0 3 , 3 4 3 2 , 3 8 6 1 , 4 2 9 0 , 4 7 1 9 , 5 1 4 8 ,
0 , 0 , 0 , 0 ,
5 5 7 7 , 6 0 0 6 , 6 4 3 5 , 6 8 6 4 , 7 2 9 3 , 7 7 2 2 , 8 1 5 1 , 8 5 8 0 , 9 0 0 9 , 9 4 3 8 , 9 8 6 7 , 1 0 2 9 6 ,
1 , - 1 , 1 , 0 ,
1 0 7 2 5 , 1 1 1 5 4 , 1 1 5 8 3 , 1 2 0 1 2 , 1 2 4 4 1 , 1 2 8 7 0 , 1 3 2 9 9 , 1 3 7 2 8 , 1 4 1 5 7 , 1 4 5 8 6 ,
1 5 0 1 5 , 1 5 4 4 4 , 1 5 8 7 3 , 1 6 3 0 2 , 1 6 7 3 1 , 1 7 1 6 0 , 1 7 5 8 9 , 1 8 0 1 8 , 1 8 4 4 7 , 1 8 8 7 6 ,
1 9 3 0 5 , 1 9 7 3 4 , 2 0 1 6 3 , 2 0 5 9 2 , 2 1 0 2 1 , 2 1 4 5 0 , 2 1 8 7 9 , 2 2 3 0 8 , 2 2 7 3 7 , 2 3 1 6 6 ,
2 3 5 9 5 , 2 4 0 2 4 , 2 4 4 5 3 , 2 4 8 8 2 , 2 5 3 1 1 , 2 5 7 4 0 , 2 6 1 6 9 , 2 6 5 9 8 , 2 7 0 2 7 , 2 7 4 5 6 ,
2 7 8 8 5 , 2 8 3 1 4 , 2 8 7 4 3 , 2 9 1 7 2 , 2 9 6 0 1 , 3 0 0 3 0 , 3 0 4 5 9 , 3 0 8 8 8 , 3 1 3 1 7 , 3 1 7 4 6 ,
3 2 1 7 5 , 3 2 6 0 4 , 3 3 0 3 3 , 3 3 4 6 2 , 3 3 8 9 1 , 3 4 3 2 0 , 3 4 7 4 9 , 3 5 1 7 8 , 3 5 6 0 7 , 3 6 0 3 6 ,
3 6 4 6 5 , 3 6 8 9 4 , 3 7 3 2 3 , 3 7 7 5 2 , 3 8 1 8 1 , 3 8 6 1 0 , 3 9 0 3 9 , 3 9 4 6 8 , 3 9 8 9 7 , 4 0 3 2 6 ,
4 0 7 5 5 , 4 1 1 8 4 , 4 1 6 1 3 , 4 2 0 4 2 , 4 2 4 7 1 , 4 2 9 0 0 , 4 3 3 2 9 , 4 3 7 5 8 , 4 4 1 8 7 , 4 4 6 1 6 ,
4 5 0 4 5 , 4 5 4 7 4 , 4 5 9 0 3 , 4 6 3 3 2 , 4 6 7 6 1 , 4 7 1 9 0 , 4 7 6 1 9 , 4 8 0 4 8 , 4 8 4 7 7 , 4 8 9 0 6 ,
4 9 3 3 5 , 4 9 7 6 4 , 5 0 1 9 3 , 5 0 6 2 2 , 5 1 0 5 1 , 5 1 4 8 0 , 5 1 9 0 9 , 5 2 3 3 8 , 5 2 7 6 7 , 5 3 1 9 6 ,
5 3 6 2 5 , 5 4 0 5 4 , 5 4 4 8 3 , 5 4 9 1 2 , 5 5 3 4 1 , 5 5 7 7 0 , 5 6 1 9 9 , 5 6 6 2 8 , 5 7 0 5 7 , 5 7 4 8 6 ,
5 7 9 1 5 , 5 8 3 4 4 , 5 8 7 7 3 , 5 9 2 0 2 , 5 9 6 3 1 , 6 0 0 6 0 , 6 0 4 8 9 , 6 0 9 1 8 , 6 1 3 4 7 , 6 1 7 7 6 ,
6 2 2 0 5 , 6 2 6 3 4 , 6 3 0 6 3 , 6 3 4 9 2 , 6 3 9 2 1 , 6 4 3 5 0 , 6 4 7 7 9 , 6 5 2 0 8 , 6 5 6 3 7 , 6 6 0 6 6 ,
6 6 4 9 5 , 6 6 9 2 4 , 6 7 3 5 3 , 6 7 7 8 2 , 6 8 2 1 1 , 6 8 6 4 0 , 6 9 0 6 9 , 6 9 4 9 8 , 6 9 9 2 7 , 7 0 3 5 6 ,
7 0 7 8 5 , 7 1 2 1 4 , 7 1 6 4 3 , 7 2 0 7 2 , 7 2 5 0 1 , 7 2 9 3 0 , 7 3 3 5 9 , 7 3 7 8 8 , 7 4 2 1 7 , 7 4 6 4 6 ,
7 5 0 7 5 , 7 5 5 0 4 , 7 5 9 3 3 , 7 6 3 6 2 , 7 6 7 9 1 , 7 7 2 2 0 , 7 7 6 4 9 , 7 8 0 7 8 , 7 8 5 0 7 , 7 8 9 3 6 ,
7 9 3 6 5 , 7 9 7 9 4 , 8 0 2 2 3 , 8 0 6 5 2 , 8 1 0 8 1 , 8 1 5 1 0 , 8 1 9 3 9 , 8 2 3 6 8 , 8 2 7 9 7 , 8 3 2 2 6 ,
8 3 6 5 5 , 8 4 0 8 4 , 8 4 5 1 3 , 8 4 9 4 2 , 8 5 3 7 1 , 8 5 8 0 0 , 8 6 2 2 9 , 8 6 6 5 8 , 8 7 0 8 7 , 8 7 5 1 6 ,
8 7 9 4 5 , 8 8 3 7 4 , 8 8 8 0 3 , 8 9 2 3 2 , 8 9 6 6 1 , 9 0 0 9 0 , 9 0 5 1 9 , 9 0 9 4 8 , 9 1 3 7 7 , 9 1 8 0 6 ,
9 2 2 3 5 , 9 2 6 6 4 , 9 3 0 9 3 , 9 3 5 2 2 , 9 3 9 5 1 , 9 4 3 8 0 , 9 4 8 0 9 , 9 5 2 3 8 , 9 5 6 6 7 , 9 6 0 9 6 ,
9 6 5 2 5 , 9 6 9 5 4 , 9 7 3 8 3 , 9 7 8 1 2 , 9 8 2 4 1 , 9 8 6 7 0 , 9 9 0 9 9 , 9 9 5 2 8 , 9 9 9 5 7 , 1 0 0 3 8 6 ,
1 0 0 8 1 5 , 1 0 1 2 4 4 , 1 0 1 6 7 3 , 1 0 2 1 0 2 , 1 0 2 5 3 1 , 1 0 2 9 6 0 , 1 0 3 3 8 9 , 1 0 3 8 1 8 , 1 0 4 2 4 7 ,
1 0 4 6 7 6 , 1 0 5 1 0 5 , 1 0 5 5 3 4 , 1 0 5 9 6 3 , 1 0 6 3 9 2 , 1 0 6 8 2 1 , 1 0 7 2 5 0 , 1 0 7 6 7 9 , 1 0 8 1 0 8 ,
1 0 8 5 3 7 , 1 0 8 9 6 6 , 1 0 9 3 9 5
} ;
} ;
private static readonly int [ ] Cr2Lut =
public static readonly int [ ] Cr =
{
{
0 , 8 3 , 1 6 6 , 2 4 9 , 3 3 2 , 4 1 5 , 4 9 8 , 5 8 1 , 6 6 4 , 7 4 7 , 8 3 0 , 9 1 3 , 9 9 6 , 1 0 7 9 , 1 1 6 2 ,
0 , 0 , 0 , 0 ,
1 2 4 5 , 1 3 2 8 , 1 4 1 1 , 1 4 9 4 , 1 5 7 7 , 1 6 6 0 , 1 7 4 3 , 1 8 2 6 , 1 9 0 9 , 1 9 9 2 , 2 0 7 5 , 2 1 5 8 ,
1 , - 1 , - 1 , 0 ,
2 2 4 1 , 2 3 2 4 , 2 4 0 7 , 2 4 9 0 , 2 5 7 3 , 2 6 5 6 , 2 7 3 9 , 2 8 2 2 , 2 9 0 5 , 2 9 8 8 , 3 0 7 1 , 3 1 5 4 ,
3 2 3 7 , 3 3 2 0 , 3 4 0 3 , 3 4 8 6 , 3 5 6 9 , 3 6 5 2 , 3 7 3 5 , 3 8 1 8 , 3 9 0 1 , 3 9 8 4 , 4 0 6 7 , 4 1 5 0 ,
4 2 3 3 , 4 3 1 6 , 4 3 9 9 , 4 4 8 2 , 4 5 6 5 , 4 6 4 8 , 4 7 3 1 , 4 8 1 4 , 4 8 9 7 , 4 9 8 0 , 5 0 6 3 , 5 1 4 6 ,
5 2 2 9 , 5 3 1 2 , 5 3 9 5 , 5 4 7 8 , 5 5 6 1 , 5 6 4 4 , 5 7 2 7 , 5 8 1 0 , 5 8 9 3 , 5 9 7 6 , 6 0 5 9 , 6 1 4 2 ,
6 2 2 5 , 6 3 0 8 , 6 3 9 1 , 6 4 7 4 , 6 5 5 7 , 6 6 4 0 , 6 7 2 3 , 6 8 0 6 , 6 8 8 9 , 6 9 7 2 , 7 0 5 5 , 7 1 3 8 ,
7 2 2 1 , 7 3 0 4 , 7 3 8 7 , 7 4 7 0 , 7 5 5 3 , 7 6 3 6 , 7 7 1 9 , 7 8 0 2 , 7 8 8 5 , 7 9 6 8 , 8 0 5 1 , 8 1 3 4 ,
8 2 1 7 , 8 3 0 0 , 8 3 8 3 , 8 4 6 6 , 8 5 4 9 , 8 6 3 2 , 8 7 1 5 , 8 7 9 8 , 8 8 8 1 , 8 9 6 4 , 9 0 4 7 , 9 1 3 0 ,
9 2 1 3 , 9 2 9 6 , 9 3 7 9 , 9 4 6 2 , 9 5 4 5 , 9 6 2 8 , 9 7 1 1 , 9 7 9 4 , 9 8 7 7 , 9 9 6 0 , 1 0 0 4 3 , 1 0 1 2 6 ,
1 0 2 0 9 , 1 0 2 9 2 , 1 0 3 7 5 , 1 0 4 5 8 , 1 0 5 4 1 , 1 0 6 2 4 , 1 0 7 0 7 , 1 0 7 9 0 , 1 0 8 7 3 , 1 0 9 5 6 ,
1 1 0 3 9 , 1 1 1 2 2 , 1 1 2 0 5 , 1 1 2 8 8 , 1 1 3 7 1 , 1 1 4 5 4 , 1 1 5 3 7 , 1 1 6 2 0 , 1 1 7 0 3 , 1 1 7 8 6 ,
1 1 8 6 9 , 1 1 9 5 2 , 1 2 0 3 5 , 1 2 1 1 8 , 1 2 2 0 1 , 1 2 2 8 4 , 1 2 3 6 7 , 1 2 4 5 0 , 1 2 5 3 3 , 1 2 6 1 6 ,
1 2 6 9 9 , 1 2 7 8 2 , 1 2 8 6 5 , 1 2 9 4 8 , 1 3 0 3 1 , 1 3 1 1 4 , 1 3 1 9 7 , 1 3 2 8 0 , 1 3 3 6 3 , 1 3 4 4 6 ,
1 3 5 2 9 , 1 3 6 1 2 , 1 3 6 9 5 , 1 3 7 7 8 , 1 3 8 6 1 , 1 3 9 4 4 , 1 4 0 2 7 , 1 4 1 1 0 , 1 4 1 9 3 , 1 4 2 7 6 ,
1 4 3 5 9 , 1 4 4 4 2 , 1 4 5 2 5 , 1 4 6 0 8 , 1 4 6 9 1 , 1 4 7 7 4 , 1 4 8 5 7 , 1 4 9 4 0 , 1 5 0 2 3 , 1 5 1 0 6 ,
1 5 1 8 9 , 1 5 2 7 2 , 1 5 3 5 5 , 1 5 4 3 8 , 1 5 5 2 1 , 1 5 6 0 4 , 1 5 6 8 7 , 1 5 7 7 0 , 1 5 8 5 3 , 1 5 9 3 6 ,
1 6 0 1 9 , 1 6 1 0 2 , 1 6 1 8 5 , 1 6 2 6 8 , 1 6 3 5 1 , 1 6 4 3 4 , 1 6 5 1 7 , 1 6 6 0 0 , 1 6 6 8 3 , 1 6 7 6 6 ,
1 6 8 4 9 , 1 6 9 3 2 , 1 7 0 1 5 , 1 7 0 9 8 , 1 7 1 8 1 , 1 7 2 6 4 , 1 7 3 4 7 , 1 7 4 3 0 , 1 7 5 1 3 , 1 7 5 9 6 ,
1 7 6 7 9 , 1 7 7 6 2 , 1 7 8 4 5 , 1 7 9 2 8 , 1 8 0 1 1 , 1 8 0 9 4 , 1 8 1 7 7 , 1 8 2 6 0 , 1 8 3 4 3 , 1 8 4 2 6 ,
1 8 5 0 9 , 1 8 5 9 2 , 1 8 6 7 5 , 1 8 7 5 8 , 1 8 8 4 1 , 1 8 9 2 4 , 1 9 0 0 7 , 1 9 0 9 0 , 1 9 1 7 3 , 1 9 2 5 6 ,
1 9 3 3 9 , 1 9 4 2 2 , 1 9 5 0 5 , 1 9 5 8 8 , 1 9 6 7 1 , 1 9 7 5 4 , 1 9 8 3 7 , 1 9 9 2 0 , 2 0 0 0 3 , 2 0 0 8 6 ,
2 0 1 6 9 , 2 0 2 5 2 , 2 0 3 3 5 , 2 0 4 1 8 , 2 0 5 0 1 , 2 0 5 8 4 , 2 0 6 6 7 , 2 0 7 5 0 , 2 0 8 3 3 , 2 0 9 1 6 ,
2 0 9 9 9 , 2 1 0 8 2 , 2 1 1 6 5
} ;
} ;
}
}
// Waiting for C# 7 stackalloc keyword patiently ...
private static class OnStackInputCache
{
public unsafe struct Byte
{
public fixed byte Data [ InputByteCount * 3 ] ;
public static Byte Create ( byte [ ] data )
{
Byte result = default ( Byte ) ;
for ( int i = 0 ; i < data . Length ; i + + )
{
result . Data [ i ] = data [ i ] ;
}
return result ;
}
}
}
public struct Result
{
internal Block8x8F Y ;
internal Block8x8F Cb ;
internal Block8x8F Cr ;
}
// The operation is defined as "RGBA -> YCbCr Transform a stream of bytes into a stream of floats"
// We need to benchmark the whole operation, to get true results, not missing any side effects!
private byte [ ] inputSourceRGB = null ;
private int [ ] inputSourceRGBAsInteger = null ;
[Setup]
public void Setup ( )
{
// Console.WriteLine("Vector<int>.Count: " + Vector<int>.Count);
this . inputSourceRGB = new byte [ InputByteCount ] ;
for ( int i = 0 ; i < this . inputSourceRGB . Length ; i + + )
{
this . inputSourceRGB [ i ] = ( byte ) ( 4 2 + i ) ;
}
this . inputSourceRGBAsInteger = new int [ InputByteCount + Vector < int > . Count ] ; // Filling this should be part of the measured operation
}
[Benchmark(Baseline = true, Description = "Floating Point Conversion")]
[Benchmark(Baseline = true, Description = "Floating Point Conversion")]
public Vector3 RgbaToYcbCr ( )
public unsafe void RgbaToYcbCrScalarFloat ( )
{
{
Vector3 v = new Vector3 ( 2 5 5 ) ;
// Copy the input to the stack:
OnStackInputCache . Byte input = OnStackInputCache . Byte . Create ( this . inputSourceRGB ) ;
float yy = ( 0.299F * v . X ) + ( 0.587F * v . Y ) + ( 0.114F * v . Z ) ;
// On-stack output:
float cb = 1 2 8 + ( ( - 0.168736F * v . X ) - ( 0.331264F * v . Y ) + ( 0.5F * v . Z ) ) ;
Result result = default ( Result ) ;
float cr = 1 2 8 + ( ( 0.5F * v . X ) - ( 0.418688F * v . Y ) - ( 0.081312F * v . Z ) ) ;
float * yPtr = ( float * ) & result . Y ;
float * cbPtr = ( float * ) & result . Cb ;
float * crPtr = ( float * ) & result . Cr ;
// end of code-bloat block :)
return new Vector3 ( yy , cb , cr ) ;
for ( int i = 0 ; i < InputColorCount ; i + + )
{
int i3 = i * 3 ;
float r = input . Data [ i3 + 0 ] ;
float g = input . Data [ i3 + 1 ] ;
float b = input . Data [ i3 + 2 ] ;
* yPtr + + = ( 0.299F * r ) + ( 0.587F * g ) + ( 0.114F * b ) ;
* cbPtr + + = 1 2 8 + ( ( - 0.168736F * r ) - ( 0.331264F * g ) + ( 0.5F * b ) ) ;
* crPtr + + = 1 2 8 + ( ( 0.5F * r ) - ( 0.418688F * g ) - ( 0.081312F * b ) ) ;
}
}
}
[Benchmark(Description = "Simd Floating Point Conversion")]
[Benchmark(Description = "Simd Floating Point Conversion")]
public Vector3 RgbaToYcbCrSimd ( )
public unsafe void RgbaToYcbCrSimdFloat ( )
{
{
Vector3 vectorRgb = new Vector3 ( 2 5 5 ) ;
// Copy the input to the stack:
OnStackInputCache . Byte input = OnStackInputCache . Byte . Create ( this . inputSourceRGB ) ;
// On-stack output:
Result result = default ( Result ) ;
float * yPtr = ( float * ) & result . Y ;
float * cbPtr = ( float * ) & result . Cb ;
float * crPtr = ( float * ) & result . Cr ;
// end of code-bloat block :)
for ( int i = 0 ; i < InputColorCount ; i + + )
{
int i3 = i * 3 ;
Vector3 vectorRgb = new Vector3 (
input . Data [ i3 + 0 ] ,
input . Data [ i3 + 1 ] ,
input . Data [ i3 + 2 ]
) ;
Vector3 vectorY = VectorY * vectorRgb ;
Vector3 vectorY = VectorY * vectorRgb ;
Vector3 vectorCb = VectorCb * vectorRgb ;
Vector3 vectorCb = VectorCb * vectorRgb ;
Vector3 vectorCr = VectorCr * vectorRgb ;
Vector3 vectorCr = VectorCr * vectorRgb ;
float yy = vectorY . X + vectorY . Y + vectorY . Z ;
// Should be better in theory, but came out to be worse: :(
float cb = 1 2 8 + ( vectorCb . X - vectorCb . Y + vectorCb . Z ) ;
// Vector3 c = new Vector3(0, 128, 128);
float cr = 1 2 8 + ( vectorCr . X - vectorCr . Y - vectorCr . Z ) ;
// Vector3 xx = new Vector3(vectorY.X, vectorCb.X, vectorCr.X);
// Vector3 yy = new Vector3(vectorY.Y, -vectorCb.Y, -vectorCr.Y);
// Vector3 zz = new Vector3(vectorY.Z, vectorCb.Z, -vectorCr.Z);
// c += xx + yy + zz;
// *yPtr++ = c.X;
// *cbPtr++ = c.Y;
// *crPtr++ = c.Z;
* yPtr + + = vectorY . X + vectorY . Y + vectorY . Z ;
* cbPtr + + = 1 2 8 + ( vectorCb . X - vectorCb . Y + vectorCb . Z ) ;
* crPtr + + = 1 2 8 + ( vectorCr . X - vectorCr . Y - vectorCr . Z ) ;
}
}
[Benchmark(Description = "Scaled Integer Conversion + Vector<int>")]
public unsafe void RgbaToYcbCrScaledIntegerSimd ( )
{
// Copy the input to the stack:
// On-stack output:
Result result = default ( Result ) ;
float * yPtr = ( float * ) & result . Y ;
float * cbPtr = ( float * ) & result . Cb ;
float * crPtr = ( float * ) & result . Cr ;
// end of code-bloat block :)
Vector < int > yCoeffs = new Vector < int > ( ScaledCoeffs . Y ) ;
Vector < int > cbCoeffs = new Vector < int > ( ScaledCoeffs . Cb ) ;
Vector < int > crCoeffs = new Vector < int > ( ScaledCoeffs . Cr ) ;
for ( int i = 0 ; i < this . inputSourceRGB . Length ; i + + )
{
this . inputSourceRGBAsInteger [ i ] = this . inputSourceRGB [ i ] ;
}
for ( int i = 0 ; i < InputColorCount ; i + = 2 )
{
Vector < int > rgb = new Vector < int > ( this . inputSourceRGBAsInteger , i * 3 ) ;
Vector < int > y = yCoeffs * rgb ;
Vector < int > cb = cbCoeffs * rgb ;
Vector < int > cr = crCoeffs * rgb ;
* yPtr + + = ( y [ 0 ] + y [ 1 ] + y [ 2 ] ) > > 1 0 ;
* cbPtr + + = 1 2 8 + ( ( cb [ 0 ] - cb [ 1 ] + cb [ 2 ] ) > > 1 0 ) ;
* crPtr + + = 1 2 8 + ( ( cr [ 0 ] - cr [ 1 ] - cr [ 2 ] ) > > 1 0 ) ;
* yPtr + + = ( y [ 4 ] + y [ 5 ] + y [ 6 ] ) > > 1 0 ;
* cbPtr + + = 1 2 8 + ( ( cb [ 4 ] - cb [ 5 ] + cb [ 6 ] ) > > 1 0 ) ;
* crPtr + + = 1 2 8 + ( ( cr [ 4 ] - cr [ 5 ] - cr [ 6 ] ) > > 1 0 ) ;
}
}
/// <summary>
/// This should perform better. Coreclr emmitted Vector.Dot() code lacks the vectorization even with IsHardwareAccelerated == true.
/// Kept this benchmark because maybe it will be improved in a future CLR release.
/// <see>
/// <cref>https://www.gamedev.net/topic/673396-c-systemnumericsvectors-slow/</cref>
/// </see>
/// </summary>
[Benchmark(Description = "Scaled Integer Conversion + Vector<int> + Dot Product")]
public unsafe void RgbaToYcbCrScaledIntegerSimdWithDotProduct ( )
{
// Copy the input to the stack:
// On-stack output:
Result result = default ( Result ) ;
float * yPtr = ( float * ) & result . Y ;
float * cbPtr = ( float * ) & result . Cb ;
float * crPtr = ( float * ) & result . Cr ;
// end of code-bloat block :)
Vector < int > yCoeffs = new Vector < int > ( ScaledCoeffs . Y ) ;
Vector < int > cbCoeffs = new Vector < int > ( ScaledCoeffs . Cb ) ;
Vector < int > crCoeffs = new Vector < int > ( ScaledCoeffs . Cr ) ;
Vector < int > leftY = new Vector < int > ( ScaledCoeffs . SelectLeft . Y ) ;
Vector < int > leftCb = new Vector < int > ( ScaledCoeffs . SelectLeft . Cb ) ;
Vector < int > leftCr = new Vector < int > ( ScaledCoeffs . SelectLeft . Cr ) ;
Vector < int > rightY = new Vector < int > ( ScaledCoeffs . SelectRight . Y ) ;
Vector < int > rightCb = new Vector < int > ( ScaledCoeffs . SelectRight . Cb ) ;
Vector < int > rightCr = new Vector < int > ( ScaledCoeffs . SelectRight . Cr ) ;
for ( int i = 0 ; i < this . inputSourceRGB . Length ; i + + )
{
this . inputSourceRGBAsInteger [ i ] = this . inputSourceRGB [ i ] ;
}
for ( int i = 0 ; i < InputColorCount ; i + = 2 )
{
Vector < int > rgb = new Vector < int > ( this . inputSourceRGBAsInteger , i * 3 ) ;
Vector < int > y = yCoeffs * rgb ;
Vector < int > cb = cbCoeffs * rgb ;
Vector < int > cr = crCoeffs * rgb ;
return new Vector3 ( yy , cb , cr ) ;
VectorizedConvertImpl ( ref yPtr , ref cbPtr , ref crPtr , y , cb , cr , leftY , leftCb , leftCr ) ;
VectorizedConvertImpl ( ref yPtr , ref cbPtr , ref crPtr , y , cb , cr , rightY , rightCb , rightCr ) ;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static unsafe void VectorizedConvertImpl (
ref float * yPtr ,
ref float * cbPtr ,
ref float * crPtr ,
Vector < int > y ,
Vector < int > cb ,
Vector < int > cr ,
Vector < int > yAgg ,
Vector < int > cbAgg ,
Vector < int > crAgg )
{
int ySum = Vector . Dot ( y , yAgg ) ;
int cbSum = Vector . Dot ( cb , cbAgg ) ;
int crSum = Vector . Dot ( cr , crAgg ) ;
* yPtr + + = ySum > > 1 0 ;
* cbPtr + + = 1 2 8 + ( cbSum > > 1 0 ) ;
* crPtr + + = 1 2 8 + ( crSum > > 1 0 ) ;
}
}
[Benchmark(Description = "Scaled Integer Conversion")]
[Benchmark(Description = "Scaled Integer Conversion")]
public Vector3 RgbaToYcbCrScaled ( )
public unsafe void RgbaToYcbCrScaledInteger ( )
{
// Copy the input to the stack:
OnStackInputCache . Byte input = OnStackInputCache . Byte . Create ( this . inputSourceRGB ) ;
// On-stack output:
Result result = default ( Result ) ;
float * yPtr = ( float * ) & result . Y ;
float * cbPtr = ( float * ) & result . Cb ;
float * crPtr = ( float * ) & result . Cr ;
// end of code-bloat block :)
for ( int i = 0 ; i < InputColorCount ; i + + )
{
{
int r = 2 5 5 ;
int i3 = i * 3 ;
int g = 2 5 5 ;
int r = input . Data [ i3 + 0 ] ;
int b = 2 5 5 ;
int g = input . Data [ i3 + 1 ] ;
int b = input . Data [ i3 + 2 ] ;
// Scale by 1024, add .5F and truncate value
// Scale by 1024, add .5F and truncate value
int y0 = 3 0 6 * r ; // (0.299F * 1024) + .5F
int y0 = 3 0 6 * r ; // (0.299F * 1024) + .5F
@ -283,25 +339,38 @@
int cr1 = 4 2 9 * g ; // (0.418688F * 1024) + .5F
int cr1 = 4 2 9 * g ; // (0.418688F * 1024) + .5F
int cr2 = 8 3 * b ; // (0.081312F * 1024) + .5F
int cr2 = 8 3 * b ; // (0.081312F * 1024) + .5F
float yy = ( y0 + y1 + y2 ) > > 1 0 ;
* yPtr + + = ( y0 + y1 + y2 ) > > 1 0 ;
float cb = 1 2 8 + ( ( cb0 - cb1 + cb2 ) > > 1 0 ) ;
* cbPtr + + = 1 2 8 + ( ( cb0 - cb1 + cb2 ) > > 1 0 ) ;
float cr = 1 2 8 + ( ( cr0 - cr1 - cr2 ) > > 1 0 ) ;
* crPtr + + = 1 2 8 + ( ( cr0 - cr1 - cr2 ) > > 1 0 ) ;
}
return new Vector3 ( yy , cb , cr ) ;
}
}
[Benchmark(Description = "Scaled Integer LUT Conversion")]
[Benchmark(Description = "Scaled Integer LUT Conversion")]
public Vector3 RgbaToYcbCrScaled Lut( )
public unsafe void RgbaToYcbCrScaledInteger Lut( )
{
{
int r = 2 5 5 ;
// Copy the input to the stack:
int g = 2 5 5 ;
OnStackInputCache . Byte input = OnStackInputCache . Byte . Create ( this . inputSourceRGB ) ;
int b = 2 5 5 ;
// On-stack output:
Result result = default ( Result ) ;
float * yPtr = ( float * ) & result . Y ;
float * cbPtr = ( float * ) & result . Cb ;
float * crPtr = ( float * ) & result . Cr ;
// end of code-bloat block :)
float yy = ( Y0Lut [ r ] + Y1Lut [ g ] + Y2Lut [ b ] ) > > 1 0 ;
for ( int i = 0 ; i < InputColorCount ; i + + )
float cb = 1 2 8 + ( ( Cb0Lut [ r ] - Cb1Lut [ g ] + Cb2Cr0Lut [ b ] ) > > 1 0 ) ;
{
float cr = 1 2 8 + ( ( Cb2Cr0Lut [ r ] - Cr1Lut [ g ] - Cr2Lut [ b ] ) > > 1 0 ) ;
int i3 = i * 3 ;
return new Vector3 ( yy , cb , cr ) ;
int r = input . Data [ i3 + 0 ] ;
int g = input . Data [ i3 + 1 ] ;
int b = input . Data [ i3 + 2 ] ;
// TODO: Maybe concatenating all the arrays in LookupTables to a flat one can improve this!
* yPtr + + = ( LookupTables . Y0 [ r ] + LookupTables . Y1 [ g ] + LookupTables . Y2 [ b ] ) > > 1 0 ;
* cbPtr + + = 1 2 8 + ( ( LookupTables . Cb0 [ r ] - LookupTables . Cb1 [ g ] + LookupTables . Cb2Cr0 [ b ] ) > > 1 0 ) ;
* crPtr + + = 1 2 8 + ( ( LookupTables . Cb2Cr0 [ r ] - LookupTables . Cr1 [ g ] - LookupTables . Cr2 [ b ] ) > > 1 0 ) ;
}
}
}
}
}
}
}