Introduction
Introduction Statistics Contact Development Disclaimer Help
blind-mosaic.c - blind - suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log
Files
Refs
README
LICENSE
---
blind-mosaic.c (4819B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include "common.h"
3
4 USAGE("[-xy] mosaic-stream")
5
6 static int tiled_x = 0;
7 static int tiled_y = 0;
8
9 #define TEST(X, Y)\
10 (!*(size_t *)(img + (Y) * mosaic->width + (X)) &&\
11 mos[(Y) * mosaic->width + (X)][0] == ch1 &&\
12 mos[(Y) * mosaic->width + (X)][1] == ch2 &&\
13 mos[(Y) * mosaic->width + (X)][2] == ch3 &&\
14 mos[(Y) * mosaic->width + (X)][3] == ch4)
15
16 #define SEARCH(TYPE, SEARCH_FUNCTION)\
17 do {\
18 typedef TYPE pixel_t[4];\
19 \
20 pixel_t *restrict mos = (pixel_t *)mbuf;\
21 pixel_t *restrict img = (pixel_t *)output;\
22 size_t n, s, e, w;\
23 \
24 *(size_t *)(img + y * mosaic->width + x) = index;\
25 \
26 n = y ? y - 1 : tiled_y ? mosaic->height - 1 : y;\
27 s = y <= mosaic->height ? y + 1 : tiled_y ? 0 : y;\
28 w = x ? x - 1 : tiled_x ? mosaic->width - 1 : x;\
29 e = x <= mosaic->width ? x + 1 : tiled_x ? 0 : x;\
30 \
31 if (TEST(x, n)) SEARCH_FUNCTION(output, mbuf, mosaic, x,…
32 if (TEST(x, s)) SEARCH_FUNCTION(output, mbuf, mosaic, x,…
33 if (TEST(e, y)) SEARCH_FUNCTION(output, mbuf, mosaic, e,…
34 if (TEST(w, y)) SEARCH_FUNCTION(output, mbuf, mosaic, w,…
35 } while (0)\
36
37 #define PROCESS(TYPE, SEARCH_FUNCTION)\
38 do {\
39 typedef TYPE pixel_t[4];\
40 \
41 static pixel_t *avg = NULL;\
42 static TYPE *cnt = NULL;\
43 static size_t size = 0;\
44 \
45 pixel_t *restrict clr = (pixel_t *)cbuf;\
46 pixel_t *restrict mos = (pixel_t *)mbuf;\
47 pixel_t *img = (pixel_t *)output;\
48 size_t index = 0;\
49 size_t x, y, i;\
50 \
51 memset(img, 0, mosaic->frame_size);\
52 \
53 for (y = 0; y < mosaic->height; y++)\
54 for (x = 0; x < mosaic->width; x++)\
55 if (!*(size_t *)(img + y * mosaic->width…
56 SEARCH_FUNCTION(img, mos, mosaic…
57 mos[y * mosaic->…
58 mos[y * mosaic->…
59 mos[y * mosaic->…
60 mos[y * mosaic->…
61 \
62 if (index > size) {\
63 size = index;\
64 avg = erealloc2(avg, size, sizeof(*avg));\
65 cnt = erealloc2(cnt, size, sizeof(*cnt));\
66 }\
67 memset(avg, 0, index * sizeof(*avg));\
68 memset(cnt, 0, index * sizeof(*cnt));\
69 \
70 for (y = 0; y < mosaic->height; y++) {\
71 for (x = 0; x < mosaic->width; x++) {\
72 i = y * mosaic->width + x;\
73 index = *(size_t *)(img + i) - 1;\
74 cnt[index] += (TYPE)1;\
75 avg[index][0] *= (cnt[index] - (TYPE)1) …
76 avg[index][1] *= (cnt[index] - (TYPE)1) …
77 avg[index][2] *= (cnt[index] - (TYPE)1) …
78 avg[index][3] *= (cnt[index] - (TYPE)1) …
79 avg[index][3] += clr[i][3] /= cnt[index]…
80 avg[index][0] += clr[i][0] *= clr[i][3];\
81 avg[index][1] += clr[i][1] *= clr[i][3];\
82 avg[index][2] += clr[i][2] *= clr[i][3];\
83 }\
84 }\
85 \
86 for (i = 0; i < index; i++) {\
87 if (avg[i][3]) {\
88 avg[i][0] /= avg[i][3];\
89 avg[i][1] /= avg[i][3];\
90 avg[i][2] /= avg[i][3];\
91 }\
92 }\
93 \
94 for (y = 0; y < mosaic->height; y++) {\
95 for (x = 0; x < mosaic->width; x++) {\
96 i = y * mosaic->width + x;\
97 index = *(size_t *)(img + i) - 1;\
98 img[i][0] = avg[index][0];\
99 img[i][1] = avg[index][1];\
100 img[i][2] = avg[index][2];\
101 img[i][3] = avg[index][3];\
102 }\
103 }\
104 \
105 (void) colour;\
106 } while (0)
107
108 static void
109 search_lf(void *restrict output, void *restrict mbuf, struct stream *mos…
110 size_t x, size_t y, size_t index, double ch1, double ch2, doub…
111 {
112 SEARCH(double, search_lf);
113 }
114
115 static void
116 search_f(void *restrict output, void *restrict mbuf, struct stream *mosa…
117 size_t x, size_t y, size_t index, float ch1, float ch2, float c…
118 {
119 SEARCH(float, search_f);
120 }
121
122 static void
123 process_lf(char *restrict output, char *restrict cbuf, char *restrict mb…
124 struct stream *colour, struct stream *mosaic)
125 {
126 PROCESS(double, search_lf);
127 }
128
129 static void
130 process_f(char *restrict output, char *restrict cbuf, char *restrict mbu…
131 struct stream *colour, struct stream *mosaic)
132 {
133 PROCESS(float, search_f);
134 }
135
136 int
137 main(int argc, char *argv[])
138 {
139 struct stream colour, mosaic;
140 void (*process)(char *restrict output, char *restrict cbuf, char…
141 struct stream *colour, struct stream *mosaic);
142
143 ARGBEGIN {
144 case 'x':
145 tiled_x = 1;
146 break;
147 case 'y':
148 tiled_y = 1;
149 break;
150 default:
151 usage();
152 } ARGEND;
153
154 if (argc != 1)
155 usage();
156
157 eopen_stream(&colour, NULL);
158 eopen_stream(&mosaic, argv[0]);
159
160 SELECT_PROCESS_FUNCTION(&colour);
161 CHECK_ALPHA(&colour);
162 CHECK_N_CHAN(&colour, 4, 4);
163
164 echeck_compat(&colour, &mosaic);
165 fprint_stream_head(stdout, &colour);
166 efflush(stdout, "<stdout>");
167 process_each_frame_two_streams(&colour, &mosaic, STDOUT_FILENO, …
168 return 0;
169 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.