blind-affine-colour.c - blind - suckless command-line video editing utility
(HTM) git clone git://git.suckless.org/blind
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
blind-affine-colour.c (3345B)
---
1 /* See LICENSE file for copyright and license details. */
2 #ifndef TYPE
3 #include "common.h"
4
5 USAGE("[-alp] matrix-stream")
6
7 static int skip_alpha = 0;
8 static int linear = 0;
9 static int per_pixel = 0;
10 static size_t dim;
11
12 #define FILE "blind-affine-colour.c"
13 #include "define-functions.h"
14
15 int
16 main(int argc, char *argv[])
17 {
18 struct stream colour, matrix;
19 void (*process)(struct stream *colour, struct stream *matrix);
20 size_t h;
21
22 ARGBEGIN {
23 case 'a':
24 skip_alpha = 1;
25 break;
26 case 'l':
27 linear = 1;
28 break;
29 case 'p':
30 per_pixel = 1;
31 break;
32 default:
33 usage();
34 } ARGEND;
35
36 if (argc != 1)
37 usage();
38
39 eopen_stream(&colour, NULL);
40 eopen_stream(&matrix, argv[0]);
41
42 SELECT_PROCESS_FUNCTION(&colour);
43 if (skip_alpha && colour.alpha_chan != -1)
44 CHECK_CHANS(&colour, == (short int)(colour.n_chan - 1), == colour.luma_chan);
45 else
46 skip_alpha = 0;
47
48 if (strcmp(colour.pixfmt, matrix.pixfmt))
49 eprintf("videos use incompatible pixel formats\n");
50
51 dim = colour.n_chan - (size_t)skip_alpha + (size_t)!linear;
52 h = matrix.height, matrix.height = dim;
53 echeck_dimensions(&matrix, WIDTH | HEIGHT, "matrix");
54 matrix.height = h;
55
56 if (per_pixel) {
57 if (matrix.height != dim * colour.height || matrix.width != dim * colour.width)
58 eprintf("the matrice should have the size %zux%zu, but are %zux%zu",
59 dim * colour.height, dim * colour.width, matrix.height, matrix.width);
60 } else {
61 if (matrix.height != dim || matrix.width != dim)
62 eprintf("the matrice should have the size %zux%zu, but are %zux%zu",
63 dim, dim, matrix.height, matrix.width);
64 }
65
66 fprint_stream_head(stdout, &colour);
67 efflush(stdout, "<stdout>");
68 process(&colour, &matrix);
69 return 0;
70 }
71
72 #else
73
74 static void
75 PROCESS(struct stream *colour, struct stream *matrix)
76 {
77 char *mbuf;
78 TYPE *mat, *pixel, V[5], M[ELEMENTSOF(V)][ELEMENTSOF(V)];
79 size_t ptr, i, j, w, x = 0, y = 0, cn;
80
81 mbuf = emalloc2(dim, matrix->row_size);
82 mat = (TYPE *)mbuf;
83 w = matrix->width * matrix->n_chan;
84 cn = colour->n_chan - (size_t)skip_alpha;
85
86 memset(M, 0, sizeof(M));
87 for (i = 0; i < ELEMENTSOF(V); i++)
88 M[i][i] = V[i] = 1;
89
90 do {
91 for (ptr = 0; ptr + colour->pixel_size <= colour->ptr; x = (x + 1) % colour->width, ptr += colour->pixel_size) {
92 if (!x) {
93 if (!y && !eread_segment(matrix, mbuf, dim * matrix->row_size))
94 break;
95 if (!per_pixel) {
96 if (!y) {
97 mat = (TYPE *)mbuf;
98 for (i = 0; i < dim; i++, mat += w)
99 for (j = 0; j < dim; j++)
100 M[i][j] = mat[j * matrix->n_chan + 1]
101 * mat[(j + 1) * matrix->n_chan - 1];
102 }
103 y = (y + 1) % colour->height;
104 }
105 }
106 if (per_pixel) {
107 mat = (TYPE *)(mbuf + x * dim * matrix->pixel_size);
108 for (i = 0; i < dim; i++, mat += w)
109 for (j = 0; j < dim; j++)
110 M[i][j] = mat[j * matrix->n_chan + 1]
111 * mat[(j + 1) * matrix->n_chan - 1];
112 }
113 pixel = (TYPE *)(colour->buf + ptr);
114 for (i = 0; i < dim; i++) {
115 V[i] = 0;
116 for (j = 0; j < cn; j++)
117 V[i] += M[i][j] * pixel[j];
118 for (; j < dim; j++)
119 V[i] += M[i][j];
120 }
121 for (i = 0; i < cn; i++)
122 pixel[i] = V[i] / V[cn];
123 }
124 ewriteall(STDOUT_FILENO, colour->buf, ptr, "<stdout>");
125 memmove(colour->buf, colour->buf + ptr, colour->ptr -= ptr);
126 } while (eread_stream(colour, SIZE_MAX));
127 if (colour->ptr)
128 eprintf("%s: incomplete frame\n", colour->file);
129
130 free(mbuf);
131 }
132
133 #endif