MythTV master
mythcolourspace.cpp
Go to the documentation of this file.
1// MythTV
2#include "mythcolourspace.h"
3
4// Qt
5#include <QtGlobal>
6
7#define D65 {0.31271F, 0.32902F}
8#define Cwp {0.31006F, 0.31616F}
9
10MythColourSpace MythColourSpace::s_sRGB = {{{{0.640F, 0.330F}, {0.300F, 0.600F}, {0.150F, 0.060F}}}, D65};
11MythColourSpace MythColourSpace::s_BT709 = {{{{0.640F, 0.330F}, {0.300F, 0.600F}, {0.150F, 0.060F}}}, D65};
12MythColourSpace MythColourSpace::s_BT610_525 = {{{{0.630F, 0.340F}, {0.310F, 0.595F}, {0.155F, 0.070F}}}, D65};
13MythColourSpace MythColourSpace::s_BT610_625 = {{{{0.640F, 0.330F}, {0.290F, 0.600F}, {0.150F, 0.060F}}}, D65};
14MythColourSpace MythColourSpace::s_BT2020 = {{{{0.708F, 0.292F}, {0.170F, 0.797F}, {0.131F, 0.046F}}}, D65};
15
16// This is currently unused because I have no material that uses it and hence cannot test it.
17// As it uses a different white point it will need an additional 'Chromatic adaption'
18// stage in the primaries conversion
19MythColourSpace MythColourSpace::s_BT470M = {{{{0.670F, 0.330F}, {0.210F, 0.710F}, {0.140F, 0.080F}}}, Cwp};
20
22 : m_primaries(Primaries),
23 m_whitePoint(WhitePoint)
24{
25}
26
27bool MythColourSpace::Alike(const MythColourSpace &First, const MythColourSpace &Second, float Fuzz)
28{
29 auto cmp = [=](float One, float Two) { return (qAbs(One - Two) < Fuzz); };
30 return cmp(First.m_primaries[0][0], Second.m_primaries[0][0]) &&
31 cmp(First.m_primaries[0][1], Second.m_primaries[0][1]) &&
32 cmp(First.m_primaries[1][0], Second.m_primaries[1][0]) &&
33 cmp(First.m_primaries[1][1], Second.m_primaries[1][1]) &&
34 cmp(First.m_primaries[2][0], Second.m_primaries[2][0]) &&
35 cmp(First.m_primaries[2][1], Second.m_primaries[2][1]) &&
36 cmp(First.m_whitePoint[0], Second.m_whitePoint[0]) &&
37 cmp(First.m_whitePoint[1], Second.m_whitePoint[1]);
38}
39
40inline float CalcBy(const MythPrimariesFloat& p, const MythPrimaryFloat w)
41{
42 float val = (((1-w[0])/w[1] - (1-p[0][0])/p[0][1]) * (p[1][0]/p[1][1] - p[0][0]/p[0][1])) -
43 ((w[0]/w[1] - p[0][0]/p[0][1]) * ((1-p[1][0])/p[1][1] - (1-p[0][0])/p[0][1]));
44 val /= (((1-p[2][0])/p[2][1] - (1-p[0][0])/p[0][1]) * (p[1][0]/p[1][1] - p[0][0]/p[0][1])) -
45 ((p[2][0]/p[2][1] - p[0][0]/p[0][1]) * ((1-p[1][0])/p[1][1] - (1-p[0][0])/p[0][1]));
46 return val;
47}
48
49inline float CalcGy(const MythPrimariesFloat& p, const MythPrimaryFloat w, const float By)
50{
51 float val = (w[0]/w[1]) - (p[0][0]/p[0][1]) - (By * (p[2][0]/p[2][1] - p[0][0]/p[0][1]));
52 val /= (p[1][0]/p[1][1]) - (p[0][0]/p[0][1]);
53 return val;
54}
55
65QMatrix4x4 MythColourSpace::RGBtoXYZ(const MythColourSpace& Primaries)
66{
67 float By = CalcBy(Primaries.m_primaries, Primaries.m_whitePoint);
68 float Gy = CalcGy(Primaries.m_primaries, Primaries.m_whitePoint, By);
69 float Ry = 1.0F - Gy - By;
70
71 return {
72 // Row 0
73 Ry * Primaries.m_primaries[0][0] / Primaries.m_primaries[0][1],
74 Gy * Primaries.m_primaries[1][0] / Primaries.m_primaries[1][1],
75 By * Primaries.m_primaries[2][0] / Primaries.m_primaries[2][1],
76 0.0F,
77 // Row 1
78 Ry, Gy, By, 0.0F,
79 // Row 2
80 Ry / Primaries.m_primaries[0][1] * (1 - Primaries.m_primaries[0][0] - Primaries.m_primaries[0][1]),
81 Gy / Primaries.m_primaries[1][1] * (1 - Primaries.m_primaries[1][0] - Primaries.m_primaries[1][1]),
82 By / Primaries.m_primaries[2][1] * (1 - Primaries.m_primaries[2][0] - Primaries.m_primaries[2][1]),
83 0.0F,
84 // Row 3
85 0.0F, 0.0F, 0.0F, 1.0F };
86}
static bool Alike(const MythColourSpace &First, const MythColourSpace &Second, float Fuzz)
static QMatrix4x4 RGBtoXYZ(const MythColourSpace &Primaries)
Create a conversion matrix for RGB to XYZ with the given primaries.
static MythColourSpace s_BT610_625
static MythColourSpace s_BT470M
MythPrimaryFloat m_whitePoint
static MythColourSpace s_BT709
static MythColourSpace s_BT610_525
MythColourSpace()=default
static MythColourSpace s_sRGB
MythPrimariesFloat m_primaries
static MythColourSpace s_BT2020
float CalcBy(const MythPrimariesFloat &p, const MythPrimaryFloat w)
#define D65
#define Cwp
float CalcGy(const MythPrimariesFloat &p, const MythPrimaryFloat w, const float By)
std::array< float, 2 > MythPrimaryFloat
std::array< MythPrimaryFloat, 3 > MythPrimariesFloat