aboutsummaryrefslogtreecommitdiffstats
path: root/libglitter_get_colour_model_conversion_matrix_double.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglitter_get_colour_model_conversion_matrix_double.c')
-rw-r--r--libglitter_get_colour_model_conversion_matrix_double.c212
1 files changed, 206 insertions, 6 deletions
diff --git a/libglitter_get_colour_model_conversion_matrix_double.c b/libglitter_get_colour_model_conversion_matrix_double.c
index eb8a87d..13ae07b 100644
--- a/libglitter_get_colour_model_conversion_matrix_double.c
+++ b/libglitter_get_colour_model_conversion_matrix_double.c
@@ -3,10 +3,6 @@
#ifndef TEST
-#define X(x, y) ((x) / (y))
-#define Z(x, y) ((1 - (x)) / (y) - 1)
-
-
#if defined(__GNUC__) && !defined(__clang__)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wunsuffixed-float-constants"
@@ -59,11 +55,14 @@ libglitter_get_colour_model_conversion_matrix_double(double matrix[3][3], double
double y1, y2, y3;
double z1, z2, z3;
+#define X(x, y) ((x) / (y))
+#define Z(x, y) ((1 - (x)) / (y) - 1)
+
/* Get colour model in CIE XYZ (the matrix is in row-major order) */
mat[0][0] = x1 = X(c1x, c1y);
mat[0][1] = x2 = X(c2x, c2y);
mat[0][2] = x3 = X(c3x, c3y);
- mat[1][3] = X(white_x, white_y) * white_Y;
+ mat[0][3] = X(white_x, white_y) * white_Y;
mat[1][0] = 1;
mat[1][1] = 1;
mat[1][2] = 1;
@@ -82,6 +81,12 @@ libglitter_get_colour_model_conversion_matrix_double(double matrix[3][3], double
*c2Yp = y2;
if (c3Yp)
*c3Yp = y3;
+ x1 *= y1;
+ x2 *= y2;
+ x3 *= y3;
+ z1 *= y1;
+ z2 *= y2;
+ z3 *= y3;
/* [x1, x2, x3; y1, y2, y3; z1, z2, z3] is
* the output RGB-to-CIE XYZ conversion matrix.
@@ -110,10 +115,205 @@ libglitter_get_colour_model_conversion_matrix_double(double matrix[3][3], double
#else
+#define TOLERANCE 0.0001
+#define TOL 4
+
+#define RX 0.412457445582367576708548995157
+#define GX 0.357575865245515878143578447634
+#define BX 0.180437247826399665973085006954
+#define RY 0.212673370378408277403536885686
+#define GY 0.715151730491031756287156895269
+#define BY 0.072174899130559869164791564344
+#define RZ 0.019333942761673460208893260415
+#define GZ 0.119191955081838593666354597644
+#define BZ 0.950302838552371742508739771438
+
+#define Rx (RX / (RX + RY + RZ))
+#define Gx (GX / (GX + GY + GZ))
+#define Bx (BX / (BX + BY + BZ))
+#define Ry (RY / (RX + RY + RZ))
+#define Gy (GY / (GX + GY + GZ))
+#define By (BY / (BX + BY + BZ))
+#define Rz (RZ / (RX + RY + RZ))
+#define Gz (GZ / (GX + GY + GZ))
+#define Bz (BZ / (BX + BY + BZ))
+
+
+static int
+eq(double a, double b)
+{
+ double r = a - b;
+ return (r < 0 ? -r : r) < TOLERANCE;
+}
+
+
int
main(void)
{
- return 0; /* TODO add test */
+ double mat[3][3], c1Y, c2Y, c3Y;
+
+#define RESET\
+ do {\
+ memset(mat, 0, sizeof(mat));\
+ c1Y = c2Y = c3Y = 0;\
+ } while (0)
+
+ RESET;
+ libglitter_get_colour_model_conversion_matrix_double(mat, Rx, Ry, Gx, Gy, Bx, By,
+ LIBGLITTER_ILLUMINANT_D65,
+ 1, &c1Y, &c2Y, &c3Y);
+ ASSERT(eq(c1Y, RY));
+ ASSERT(eq(c2Y, GY));
+ ASSERT(eq(c3Y, BY));
+ ASSERT(eq(mat[0][0], RX));
+ ASSERT(eq(mat[1][0], GX));
+ ASSERT(eq(mat[2][0], BX));
+ ASSERT(eq(mat[0][1], RY));
+ ASSERT(eq(mat[1][1], GY));
+ ASSERT(eq(mat[2][1], BY));
+ ASSERT(eq(mat[0][2], RZ));
+ ASSERT(eq(mat[1][2], GZ));
+ ASSERT(eq(mat[2][2], BZ));
+
+ RESET;
+ libglitter_get_colour_model_conversion_matrix_double(mat, Rx, Ry, Gx, Gy, Bx, By,
+ LIBGLITTER_ILLUMINANT_D65,
+ 1, &c1Y, &c2Y, NULL);
+ ASSERT(eq(c1Y, RY));
+ ASSERT(eq(c2Y, GY));
+ ASSERT(eq(mat[0][0], RX));
+ ASSERT(eq(mat[1][0], GX));
+ ASSERT(eq(mat[2][0], BX));
+ ASSERT(eq(mat[0][1], RY));
+ ASSERT(eq(mat[1][1], GY));
+ ASSERT(eq(mat[2][1], BY));
+ ASSERT(eq(mat[0][2], RZ));
+ ASSERT(eq(mat[1][2], GZ));
+ ASSERT(eq(mat[2][2], BZ));
+
+ RESET;
+ libglitter_get_colour_model_conversion_matrix_double(mat, Rx, Ry, Gx, Gy, Bx, By,
+ LIBGLITTER_ILLUMINANT_D65,
+ 1, &c1Y, NULL, &c3Y);
+ ASSERT(eq(c1Y, RY));
+ ASSERT(eq(c3Y, BY));
+ ASSERT(eq(mat[0][0], RX));
+ ASSERT(eq(mat[1][0], GX));
+ ASSERT(eq(mat[2][0], BX));
+ ASSERT(eq(mat[0][1], RY));
+ ASSERT(eq(mat[1][1], GY));
+ ASSERT(eq(mat[2][1], BY));
+ ASSERT(eq(mat[0][2], RZ));
+ ASSERT(eq(mat[1][2], GZ));
+ ASSERT(eq(mat[2][2], BZ));
+
+ RESET;
+ libglitter_get_colour_model_conversion_matrix_double(mat, Rx, Ry, Gx, Gy, Bx, By,
+ LIBGLITTER_ILLUMINANT_D65,
+ 1, &c1Y, NULL, NULL);
+ ASSERT(eq(c1Y, RY));
+ ASSERT(eq(mat[0][0], RX));
+ ASSERT(eq(mat[1][0], GX));
+ ASSERT(eq(mat[2][0], BX));
+ ASSERT(eq(mat[0][1], RY));
+ ASSERT(eq(mat[1][1], GY));
+ ASSERT(eq(mat[2][1], BY));
+ ASSERT(eq(mat[0][2], RZ));
+ ASSERT(eq(mat[1][2], GZ));
+ ASSERT(eq(mat[2][2], BZ));
+
+ RESET;
+ libglitter_get_colour_model_conversion_matrix_double(mat, Rx, Ry, Gx, Gy, Bx, By,
+ LIBGLITTER_ILLUMINANT_D65,
+ 1, NULL, &c2Y, &c3Y);
+ ASSERT(eq(c2Y, GY));
+ ASSERT(eq(c3Y, BY));
+ ASSERT(eq(mat[0][0], RX));
+ ASSERT(eq(mat[1][0], GX));
+ ASSERT(eq(mat[2][0], BX));
+ ASSERT(eq(mat[0][1], RY));
+ ASSERT(eq(mat[1][1], GY));
+ ASSERT(eq(mat[2][1], BY));
+ ASSERT(eq(mat[0][2], RZ));
+ ASSERT(eq(mat[1][2], GZ));
+ ASSERT(eq(mat[2][2], BZ));
+
+ RESET;
+ libglitter_get_colour_model_conversion_matrix_double(mat, Rx, Ry, Gx, Gy, Bx, By,
+ LIBGLITTER_ILLUMINANT_D65,
+ 1, NULL, &c2Y, NULL);
+ ASSERT(eq(c2Y, GY));
+ ASSERT(eq(mat[0][0], RX));
+ ASSERT(eq(mat[1][0], GX));
+ ASSERT(eq(mat[2][0], BX));
+ ASSERT(eq(mat[0][1], RY));
+ ASSERT(eq(mat[1][1], GY));
+ ASSERT(eq(mat[2][1], BY));
+ ASSERT(eq(mat[0][2], RZ));
+ ASSERT(eq(mat[1][2], GZ));
+ ASSERT(eq(mat[2][2], BZ));
+
+ RESET;
+ libglitter_get_colour_model_conversion_matrix_double(mat, Rx, Ry, Gx, Gy, Bx, By,
+ LIBGLITTER_ILLUMINANT_D65,
+ 1, NULL, NULL, &c3Y);
+ ASSERT(eq(c3Y, BY));
+ ASSERT(eq(mat[0][0], RX));
+ ASSERT(eq(mat[1][0], GX));
+ ASSERT(eq(mat[2][0], BX));
+ ASSERT(eq(mat[0][1], RY));
+ ASSERT(eq(mat[1][1], GY));
+ ASSERT(eq(mat[2][1], BY));
+ ASSERT(eq(mat[0][2], RZ));
+ ASSERT(eq(mat[1][2], GZ));
+ ASSERT(eq(mat[2][2], BZ));
+
+ RESET;
+ libglitter_get_colour_model_conversion_matrix_double(mat, Rx, Ry, Gx, Gy, Bx, By,
+ LIBGLITTER_ILLUMINANT_D65,
+ 1, NULL, NULL, NULL);
+ ASSERT(eq(mat[0][0], RX));
+ ASSERT(eq(mat[1][0], GX));
+ ASSERT(eq(mat[2][0], BX));
+ ASSERT(eq(mat[0][1], RY));
+ ASSERT(eq(mat[1][1], GY));
+ ASSERT(eq(mat[2][1], BY));
+ ASSERT(eq(mat[0][2], RZ));
+ ASSERT(eq(mat[1][2], GZ));
+ ASSERT(eq(mat[2][2], BZ));
+
+ RESET;
+ libglitter_get_colour_model_conversion_matrix_double(mat, Rx, Ry, Gx, Gy, Bx, By,
+ LIBGLITTER_ILLUMINANT_D65,
+ 0, &c1Y, &c2Y, &c3Y);
+ ASSERT(eq(c1Y, RY));
+ ASSERT(eq(c2Y, GY));
+ ASSERT(eq(c3Y, BY));
+ ASSERT(eq(mat[0][0], 1));
+ ASSERT(eq(mat[1][0], 0));
+ ASSERT(eq(mat[2][0], 0));
+ ASSERT(eq(mat[0][1], 0));
+ ASSERT(eq(mat[1][1], 1));
+ ASSERT(eq(mat[2][1], 0));
+ ASSERT(eq(mat[0][2], 0));
+ ASSERT(eq(mat[1][2], 0));
+ ASSERT(eq(mat[2][2], 1));
+
+ RESET;
+ libglitter_get_colour_model_conversion_matrix_double(mat, Rx, Ry, Gx, Gy, Bx, By,
+ LIBGLITTER_ILLUMINANT_D65,
+ 0, NULL, NULL, NULL);
+ ASSERT(eq(mat[0][0], 1));
+ ASSERT(eq(mat[1][0], 0));
+ ASSERT(eq(mat[2][0], 0));
+ ASSERT(eq(mat[0][1], 0));
+ ASSERT(eq(mat[1][1], 1));
+ ASSERT(eq(mat[2][1], 0));
+ ASSERT(eq(mat[0][2], 0));
+ ASSERT(eq(mat[1][2], 0));
+ ASSERT(eq(mat[2][2], 1));
+
+ return 0;
}