kodi
ConversionMatrix.h
1 /*
2  * Copyright (C) 2005-2018 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: LGPL-2.1-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include <array>
12 #include <cmath>
13 #include <memory>
14 
15 extern "C" {
16 #include <libavutil/pixfmt.h>
17 }
18 
19 template<uint8_t Order>
20 class CMatrix
21 {
22 public:
23  CMatrix() = default;
24  explicit CMatrix(const CMatrix<Order - 1>& other);
25  explicit CMatrix(const std::array<std::array<float, Order>, Order>& other) : m_mat(other) {}
26  explicit CMatrix(const std::array<std::array<float, Order - 1>, Order - 1>& other);
27  virtual ~CMatrix() = default;
28 
29  virtual CMatrix operator*(const std::array<std::array<float, Order>, Order>& other);
30 
31  CMatrix operator*(const CMatrix& other);
32  CMatrix& operator*=(const CMatrix& other);
33 
34  CMatrix& operator=(const std::array<std::array<float, Order - 1>, Order - 1>& other);
35 
36  bool operator==(const CMatrix<Order>& other) const
37  {
38  for (int i = 0; i < Order; ++i)
39  {
40  for (int j = 0; j < Order; ++j)
41  {
42  if (m_mat[i][j] == other.m_mat[i][j])
43  continue;
44 
45  // some floating point comparisons should be done by checking if the difference is within a tolerance
46  if (std::abs(m_mat[i][j] - other.m_mat[i][j]) <=
47  (std::max(std::abs(other.m_mat[i][j]), std::abs(m_mat[i][j])) * 1e-2f))
48  continue;
49 
50  return false;
51  }
52  }
53 
54  return true;
55  }
56 
57  std::array<float, Order>& operator[](int index) { return m_mat[index]; }
58 
59  const std::array<float, Order>& operator[](int index) const { return m_mat[index]; }
60 
61  std::array<std::array<float, Order>, Order>& Get();
62 
63  const std::array<std::array<float, Order>, Order>& Get() const;
64 
65  CMatrix& Invert();
66 
67  float* ToRaw() { return &m_mat[0][0]; }
68 
69 protected:
70  std::array<std::array<float, Order>, Order> Invert(
71  std::array<std::array<float, Order>, Order>& other) const;
72 
73  std::array<std::array<float, Order>, Order> m_mat{{}};
74 };
75 
76 class CGlMatrix : public CMatrix<4>
77 {
78 public:
79  CGlMatrix() = default;
80  explicit CGlMatrix(const CMatrix<3>& other);
81  explicit CGlMatrix(const std::array<std::array<float, 3>, 3>& other);
82  ~CGlMatrix() override = default;
83  CMatrix operator*(const std::array<std::array<float, 4>, 4>& other) override;
84 };
85 
86 class CScale : public CGlMatrix
87 {
88 public:
89  CScale(float x, float y, float z);
90  ~CScale() override = default;
91 };
92 
93 class CTranslate : public CGlMatrix
94 {
95 public:
96  CTranslate(float x, float y, float z);
97  ~CTranslate() override = default;
98 };
99 
100 class ConversionToRGB : public CMatrix<3>
101 {
102 public:
103  ConversionToRGB(float Kr, float Kb);
104  ~ConversionToRGB() override = default;
105 
106 protected:
107  ConversionToRGB() = default;
108 
109  float a11, a12, a13;
110  float CbDen, CrDen;
111 };
112 
113 class PrimaryToXYZ : public CMatrix<3>
114 {
115 public:
116  PrimaryToXYZ(const float (&primaries)[3][2], const float (&whitepoint)[2]);
117  ~PrimaryToXYZ() override = default;
118 
119 protected:
120  PrimaryToXYZ() = default;
121  float CalcBy(const float p[3][2], const float w[2]);
122  float CalcGy(const float p[3][2], const float w[2], const float By);
123  float CalcRy(const float By, const float Gy);
124 };
125 
127 {
128 public:
129  PrimaryToRGB(float (&primaries)[3][2], float (&whitepoint)[2]);
130  ~PrimaryToRGB() override = default;
131 };
132 
133 //------------------------------------------------------------------------------
134 
135 using Matrix4 = CMatrix<4>;
136 using Matrix3 = CMatrix<3>;
137 using Matrix3x1 = std::array<float, 3>;
138 
145 {
146 public:
147  CConvertMatrix() = default;
148  ~CConvertMatrix() = default;
149 
153  CConvertMatrix& SetSourceColorSpace(AVColorSpace colorSpace);
154 
158  CConvertMatrix& SetSourceBitDepth(int bits);
159 
163  CConvertMatrix& SetSourceLimitedRange(bool limited);
164 
170  CConvertMatrix& SetSourceTextureBitDepth(int textureBits);
171 
175  CConvertMatrix& SetSourceColorPrimaries(AVColorPrimaries src);
176 
180  CConvertMatrix& SetDestinationColorPrimaries(AVColorPrimaries dst);
181 
185  CConvertMatrix& SetDestinationContrast(float contrast);
186 
190  CConvertMatrix& SetDestinationBlack(float black);
191 
195  CConvertMatrix& SetDestinationLimitedRange(bool limited);
196 
200  Matrix4 GetYuvMat();
201 
205  Matrix3 GetPrimMat();
206 
210  float GetGammaSrc();
211 
215  float GetGammaDst();
216 
220  static Matrix3x1 GetRGBYuvCoefs(AVColorSpace colspace);
221 
222 private:
223  const CGlMatrix& GenMat();
224  const CMatrix<3>& GenPrimMat();
225 
226  std::unique_ptr<CGlMatrix> m_mat;
227  std::unique_ptr<CMatrix<3>> m_matPrim;
228 
229  AVColorSpace m_colSpace = AVCOL_SPC_BT709;
230  AVColorPrimaries m_colPrimariesSrc = AVCOL_PRI_BT709;
231  float m_gammaSrc = 2.2f;
232  bool m_limitedSrc = true;
233  AVColorPrimaries m_colPrimariesDst = AVCOL_PRI_BT709;
234  float m_gammaDst = 2.2f;
235  bool m_limitedDst = false;
236  int m_srcBits = 8;
237  int m_srcTextureBits = 8;
238  float m_contrast = 1.0;
239  float m_black = 0.0;
240 };
Helper class used for YUV to RGB conversions.
Definition: ConversionMatrix.h:144
Definition: ConversionMatrix.h:20
Definition: ConversionMatrix.h:100
Definition: ConversionMatrix.h:113
Definition: ConversionMatrix.h:76
Definition: ConversionMatrix.h:126
Definition: ConversionMatrix.h:86
Definition: ConversionMatrix.h:93