blind-colour-matrix.c - blind - suckless command-line video editing utility | |
git clone git://git.suckless.org/blind | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
blind-colour-matrix.c (3441B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include "common.h" | |
3 | |
4 USAGE("[-F pixel-format] (-z x1 y1 x2 y2 x3 y3 [white-x white-y] | X1 Y1… | |
5 | |
6 static void | |
7 invert(double M[3][6]) | |
8 { | |
9 size_t r1, r2, i; | |
10 double t; | |
11 for (r1 = 0; r1 < 3; r1++) { | |
12 if (!M[r1][r1]) { | |
13 for (r2 = r1 + 1; r2 < 3 && !M[r2][r1]; r2++); | |
14 if (r2 >= 3) | |
15 eprintf("the colour space's rank is less… | |
16 for (i = 0; i < 6; i++) | |
17 t = M[r1][i], M[r1][i] = M[r2][i], M[r2]… | |
18 } | |
19 t = 1. / M[r1][r1]; | |
20 for (i = 0; i < 6; i++) | |
21 M[r1][i] *= t; | |
22 for (r2 = r1 + 1; r2 < 3; r2++) | |
23 for (i = 0, t = M[r2][r1]; i < 6; i++) | |
24 M[r2][i] -= M[r1][i] * t; | |
25 } | |
26 for (r1 = 3; --r1;) | |
27 for (r2 = r1; r2--;) | |
28 for (i = 0, t = M[r2][r1]; i < 6; i++) | |
29 M[r2][i] -= M[r1][i] * t; | |
30 } | |
31 | |
32 int | |
33 main(int argc, char *argv[]) | |
34 { | |
35 static struct stream stream = { .width = 3, .height = 3, .frames… | |
36 const char *pixfmt = "xyza"; | |
37 int ciexyy = 0; | |
38 double x[4], y[4], z[4], M[3][6], t; | |
39 double Mlf[9 * 4]; | |
40 float Mf[9 * 4]; | |
41 size_t i, j; | |
42 | |
43 ARGBEGIN { | |
44 case 'F': | |
45 pixfmt = UARGF(); | |
46 break; | |
47 case 'z': | |
48 ciexyy = 1; | |
49 break; | |
50 default: | |
51 usage(); | |
52 } ARGEND; | |
53 | |
54 if (argc != (3 - ciexyy) * 3 && argc != (3 - ciexyy) * 4) | |
55 usage(); | |
56 | |
57 if (ciexyy) { | |
58 x[0] = etolf_arg("x1", argv[0]); | |
59 y[0] = etolf_arg("y1", argv[1]); | |
60 x[1] = etolf_arg("x2", argv[2]); | |
61 y[1] = etolf_arg("y2", argv[3]); | |
62 x[2] = etolf_arg("x3", argv[4]); | |
63 y[2] = etolf_arg("y3", argv[5]); | |
64 x[3] = argc > 6 ? etolf_arg("white-x", argv[6]) : D65_XY… | |
65 y[3] = argc > 6 ? etolf_arg("white-y", argv[7]) : D65_XY… | |
66 for (i = 0; i < 4; i++) { | |
67 if (y[i]) { | |
68 z[i] = (1. - x[i] - y[i]) / y[i]; | |
69 x[i] /= y[i]; | |
70 y[i] = 1.; | |
71 } else { | |
72 x[i] = y[i] = z[i] = 1.; | |
73 } | |
74 } | |
75 } else { | |
76 x[0] = etolf_arg("X1", argv[0]); | |
77 y[0] = etolf_arg("Y1", argv[1]); | |
78 z[0] = etolf_arg("Z1", argv[2]); | |
79 x[1] = etolf_arg("X2", argv[3]); | |
80 y[1] = etolf_arg("Y2", argv[4]); | |
81 z[1] = etolf_arg("Z2", argv[5]); | |
82 x[2] = etolf_arg("X3", argv[6]); | |
83 y[2] = etolf_arg("Y3", argv[7]); | |
84 z[2] = etolf_arg("Z3", argv[8]); | |
85 x[3] = argc > 9 ? etolf_arg("white-X", argv[9]) : D65_X… | |
86 y[3] = argc > 9 ? etolf_arg("white-Y", argv[10]) : 1; | |
87 z[3] = argc > 9 ? etolf_arg("white-Z", argv[11]) : D65_X… | |
88 } | |
89 | |
90 for (i = 0; i < 3; i++) { | |
91 M[0][i] = x[i]; | |
92 M[1][i] = y[i]; | |
93 M[2][i] = z[i]; | |
94 M[i][3] = M[i][4] = M[i][5] = 0.; | |
95 M[i][3 + i] = 1.; | |
96 } | |
97 | |
98 invert(M); | |
99 | |
100 for (i = 0; i < 3; i++) { | |
101 t = M[i][3] * x[3] + M[i][4] * y[3] + M[i][5] * z[3]; | |
102 M[0][i] = t * x[i]; | |
103 M[1][i] = t * y[i]; | |
104 M[2][i] = t * z[i]; | |
105 } | |
106 | |
107 for (i = 0; i < 3; i++) { | |
108 M[i][3] = M[i][4] = M[i][5] = 0.; | |
109 M[i][3 + i] = 1.; | |
110 } | |
111 | |
112 invert(M); | |
113 | |
114 eset_pixel_format(&stream, pixfmt); | |
115 fprint_stream_head(stdout, &stream); | |
116 efflush(stdout, "<stdout>"); | |
117 | |
118 for (i = 0; i < 3; i++) { | |
119 for (j = 0; j < 3; j++) { | |
120 Mlf[i * 12 + j * 4 + 0] = M[i][3 + j]; | |
121 Mlf[i * 12 + j * 4 + 1] = M[i][3 + j]; | |
122 Mlf[i * 12 + j * 4 + 2] = M[i][3 + j]; | |
123 Mlf[i * 12 + j * 4 + 3] = 1.; | |
124 } | |
125 } | |
126 | |
127 CHECK_ALPHA_CHAN(&stream); | |
128 CHECK_COLOUR_SPACE(&stream, CIEXYZ); | |
129 if (stream.encoding == DOUBLE) { | |
130 ewriteall(STDOUT_FILENO, Mlf, sizeof(Mlf), "<stdout>"); | |
131 } else if (stream.encoding == FLOAT) { | |
132 for (i = 0; i < ELEMENTSOF(Mlf); i++) | |
133 Mf[i] = (float)Mlf[i]; | |
134 ewriteall(STDOUT_FILENO, Mf, sizeof(Mf), "<stdout>"); | |
135 } else { | |
136 eprintf("pixel format %s is not supported, try xyza\n", … | |
137 } | |
138 | |
139 return 0; | |
140 } |