blind-make-kernel.c - blind - suckless command-line video editing utility | |
git clone git://git.suckless.org/blind | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
blind-make-kernel.c (3372B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include "common.h" | |
3 | |
4 USAGE("[-d denominator] ... [-nxyza] [-- value ...] ...") | |
5 | |
6 static void | |
7 new_row(double **kernel, size_t *col, size_t *rows, size_t *cols) | |
8 { | |
9 if (!*col) | |
10 return; | |
11 if (*rows && *col != *cols) | |
12 eprintf("the rows in the matrix do not have the same num… | |
13 *kernel = erealloc3(*kernel, 1 + ++*rows, *cols = *col, sizeof(*… | |
14 *col = 0; | |
15 } | |
16 | |
17 static void | |
18 new_col(char *arg, double **kernel, size_t *col, size_t *rows, size_t *c… | |
19 { | |
20 if (*rows && *col >= *cols) | |
21 eprintf("the rows in the matrix do not have the same num… | |
22 if (!*rows) | |
23 *kernel = erealloc2(*kernel, *col + 1, sizeof(**kernel)); | |
24 if (tolf(arg, &(*kernel)[*rows * *cols + (*col)++])) | |
25 eprintf("matrix cell values must be floating-point value… | |
26 } | |
27 | |
28 static void | |
29 finalise(double **kernel, size_t col, size_t *rows, size_t *cols) | |
30 { | |
31 if (col) | |
32 new_row(kernel, &col, rows, cols); | |
33 if (!*rows) | |
34 eprintf("the matrix cannot be null-sized\n"); | |
35 } | |
36 | |
37 static double * | |
38 read_matrix_cmdline(char *args[], size_t *rows, size_t *cols) | |
39 { | |
40 size_t col = 0; | |
41 double *kernel = NULL; | |
42 *rows = *cols = 0; | |
43 for (; *args; args++) { | |
44 if (!strcmp(*args, "--")) | |
45 new_row(&kernel, &col, rows, cols); | |
46 else | |
47 new_col(*args, &kernel, &col, rows, cols); | |
48 } | |
49 finalise(&kernel, col, rows, cols); | |
50 return kernel; | |
51 } | |
52 | |
53 static double * | |
54 read_matrix_stdin(size_t *rows, size_t *cols) | |
55 { | |
56 char *line = NULL, *p, *q; | |
57 size_t size = 0, col = 0; | |
58 double *kernel = NULL; | |
59 ssize_t len; | |
60 *rows = *cols = 0; | |
61 while ((len = getline(&line, &size, stdin)) >= 0) { | |
62 col = 0; | |
63 for (p = line;; p = q) { | |
64 while (*p && isspace(*p)) p++; | |
65 if (!*(q = p)) | |
66 break; | |
67 while (*q && !isspace(*q)) q++; | |
68 *q++ = '\0'; | |
69 new_col(p, &kernel, &col, rows, cols); | |
70 } | |
71 new_row(&kernel, &col, rows, cols); | |
72 } | |
73 free(line); | |
74 if (ferror(stdout)) | |
75 eprintf("getline:"); | |
76 finalise(&kernel, col, rows, cols); | |
77 return kernel; | |
78 } | |
79 | |
80 int | |
81 main(int argc, char *argv[]) | |
82 { | |
83 int normalise = 0; | |
84 double denominator = 1; | |
85 int id_x = 1, id_y = 1, id_z = 1, id_a = 1; | |
86 size_t rows, cols, y, x, n; | |
87 double *kernel, *kern, sum = 0, value; | |
88 double *buffer, *buf, id_val; | |
89 | |
90 ARGBEGIN { | |
91 case 'd': | |
92 denominator *= etolf_flag('d', UARGF()); | |
93 break; | |
94 case 'n': | |
95 normalise = 1; | |
96 break; | |
97 case 'x': | |
98 id_x = 0; | |
99 break; | |
100 case 'y': | |
101 id_y = 0; | |
102 break; | |
103 case 'z': | |
104 id_z = 0; | |
105 break; | |
106 case 'a': | |
107 id_a = 0; | |
108 break; | |
109 default: | |
110 usage(); | |
111 } ARGEND; | |
112 | |
113 if (id_x && id_y && id_z && id_a) | |
114 id_x = id_y = id_z = id_a = 0; | |
115 | |
116 if (argc) | |
117 kernel = read_matrix_cmdline(argv, &rows, &cols); | |
118 else | |
119 kernel = read_matrix_stdin(&rows, &cols); | |
120 | |
121 FPRINTF_HEAD(stdout, (size_t)1, cols, rows, "xyza"); | |
122 efflush(stdout, "<stdout>"); | |
123 | |
124 buffer = emalloc2(cols, 4 * sizeof(double)); | |
125 n = cols * 4 * sizeof(double); | |
126 | |
127 if (normalise) { | |
128 kern = kernel; | |
129 for (y = 0; y < rows; y++) | |
130 for (x = 0; x < cols; x++) | |
131 sum += *kern++; | |
132 denominator *= sum; | |
133 } | |
134 | |
135 kern = kernel; | |
136 for (y = 0; y < rows; y++) { | |
137 buf = buffer; | |
138 for (x = 0; x < cols; x++) { | |
139 id_val = (x == cols / 2 && y == rows / 2) ? 1. :… | |
140 value = *kern++ / denominator; | |
141 buf[0] = id_x ? id_val : value; | |
142 buf[1] = id_y ? id_val : value; | |
143 buf[2] = id_z ? id_val : value; | |
144 buf[3] = id_a ? id_val : value; | |
145 buf += 4; | |
146 } | |
147 ewriteall(STDOUT_FILENO, buffer, n, "<stdout>"); | |
148 } | |
149 | |
150 free(kernel); | |
151 free(buffer); | |
152 return 0; | |
153 } |