blind-affine-colour.c - blind - suckless command-line video editing utility | |
git clone git://git.suckless.org/blind | |
Log | |
Files | |
Refs | |
README | |
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), … | |
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… | |
58 eprintf("the matrice should have the size %zux%z… | |
59 dim * colour.height, dim * colour.width,… | |
60 } else { | |
61 if (matrix.height != dim || matrix.width != dim) | |
62 eprintf("the matrice should have the size %zux%z… | |
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… | |
92 if (!x) { | |
93 if (!y && !eread_segment(matrix, mbuf, d… | |
94 break; | |
95 if (!per_pixel) { | |
96 if (!y) { | |
97 mat = (TYPE *)mbuf; | |
98 for (i = 0; i < dim; i++… | |
99 for (j = 0; j < … | |
100 M[i][j] … | |
101 … | |
102 } | |
103 y = (y + 1) % colour->height; | |
104 } | |
105 } | |
106 if (per_pixel) { | |
107 mat = (TYPE *)(mbuf + x * dim * matrix->… | |
108 for (i = 0; i < dim; i++, mat += w) | |
109 for (j = 0; j < dim; j++) | |
110 M[i][j] = mat[j * matrix… | |
111 * mat[(j + 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 -= p… | |
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 |