34 const i64 ux =
static_cast<i64>(
g[0]) - r[0];
35 const i64 uy =
static_cast<i64>(
g[1]) - r[1];
36 const i64 vx =
static_cast<i64>(b[0]) - r[0];
37 const i64 vy =
static_cast<i64>(b[1]) - r[1];
38 const i64 twice_area_q32 = ux * vy - uy * vx;
39 constexpr i64 kMinTwiceAreaQ32 = 429497;
40 return twice_area_q32 > kMinTwiceAreaQ32 || twice_area_q32 < -kMinTwiceAreaQ32;
47 const i64 acc =
static_cast<i64>(row[0]) *
static_cast<i64>(r)
48 +
static_cast<i64>(row[1]) *
static_cast<i64>(
g)
49 +
static_cast<i64>(row[2]) *
static_cast<i64>(b);
52 return static_cast<i32
>((acc + 32768) >> 16);
70 if (!sourceChromaticityQ16(primaries.red, xy_r) ||
71 !sourceChromaticityQ16(primaries.green, xy_g) ||
72 !sourceChromaticityQ16(primaries.blue, xy_b) ||
73 !sourceChromaticityQ16(primaries.white, xy_w)) {
76 if (!sourcePrimariesEncloseAreaQ16(xy_r, xy_g, xy_b)) {
89 const i32 primaries_xyz[3][3] = {
90 {
static_cast<i32
>(red[0]),
static_cast<i32
>(green[0]),
static_cast<i32
>(blue[0])},
91 {
static_cast<i32
>(red[1]),
static_cast<i32
>(green[1]),
static_cast<i32
>(blue[1])},
92 {
static_cast<i32
>(red[2]),
static_cast<i32
>(green[2]),
static_cast<i32
>(blue[2])},
98 const i32 white_xyz[3] = {
static_cast<i32
>(white[0]),
static_cast<i32
>(white[1]),
99 static_cast<i32
>(white[2])};
101 for (
int i = 0; i < 3; ++i) {
104 for (
int row = 0; row < 3; ++row) {
105 for (
int col = 0; col < 3; ++col) {
106 const i64 product =
static_cast<i64>(primaries_xyz[row][col]) * k[col];
107 out->m[row][col] =
static_cast<i32
>(
116 out_xyz[0] = dotRowQ16(matrix.
m[0], r,
g, b);
117 out_xyz[1] = dotRowQ16(matrix.
m[1], r,
g, b);
118 out_xyz[2] = dotRowQ16(matrix.
m[2], r,
g, b);
bool sourcePrimariesEncloseAreaQ16(const i32(&r)[2], const i32(&g)[2], const i32(&b)[2]) FL_NO_EXCEPT
True when the three primaries enclose an actual area of chromaticity.
i32 dotRowQ16(const i32(&row)[3], u16 r, u16 g, u16 b) FL_NO_EXCEPT
One matrix row against the pixel.
bool sourceChromaticityQ16(Chromaticity c, i32(&out)[2]) FL_NO_EXCEPT
A chromaticity, converted from float by its bits, that is real and usable: inside the open unit squar...
constexpr i32 kSourceQ16One
i32 dotRowQ16(const i32(&row)[3], const i32(&v)[3]) FL_NO_EXCEPT
One s16.16 matrix row against a vector, rounded and saturated.
i64 roundedDivideQ16(i64 numerator, i64 denominator) FL_NO_EXCEPT
The s16.16 building blocks the bind-time builders share.
bool xyzColumnQ16(const i32(&xy)[2], i32 luminance, i64(&column)[3]) FL_NO_EXCEPT
XYZ of chromaticity xy at luminance luminance, all s16.16; false for a non-positive or out-of-simplex...
bool buildSourceMatrixQ16(const RgbPrimaries &primaries, SourceMatrixQ16 *out) FL_NO_EXCEPT
Quantize the source matrix for primaries.
InputGamut g FL_NO_EXCEPT
void linearRgbToXyzQ16(const SourceMatrixQ16 &matrix, u16 r, u16 g, u16 b, i32(&out_xyz)[3]) FL_NO_EXCEPT
One pixel: u16 linear RGB -> s16.16 XYZ.
bool invert3x3Q16(const i32(&in)[3][3], i32(&out)[3][3]) FL_NO_EXCEPT
Inverse of an s16.16 3x3 matrix, in s16.16, computed without floats.
bool q16FromFloatBits(float value, i32 *out) FL_NO_EXCEPT
s16.16 of a float, rounded to nearest, computed from its IEEE-754 bits with integer arithmetic only –...
Base definition for an LED controller.
Source-primaries matrix in s16.16, rows ordered X, Y, Z.
CIE 1931 xy chromaticity, independent of encoded storage and chipset.