Introduction
Introduction Statistics Contact Development Disclaimer Help
blind-from-image.c - blind - suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log
Files
Refs
README
LICENSE
---
blind-from-image.c (6714B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include "common.h"
3
4 USAGE("[-h] [-f | -p]")
5
6 static char buf[BUFSIZ];
7 static char width[INTSTRLEN(size_t) + 1] = {0};
8 static char height[INTSTRLEN(size_t) + 1] = {0};
9 static const char *conv_fail_msg = "convertion failed, if converting a f…
10 static size_t pixel_size;
11 static double value_max;
12 static double (*get_value)(char **bufp);
13 static void (*convert)(size_t n);
14 static int with_alpha = 1;
15 static int with_colour = 1;
16
17 static double
18 get_value_u8(char** bufp)
19 {
20 uint8_t value = *(uint8_t *)(*bufp);
21 *bufp += 1;
22 return (double)value / (double)value_max;
23 }
24
25 static double
26 get_value_u16(char** bufp)
27 {
28 uint16_t value = ntohs(*(uint16_t *)(*bufp));
29 *bufp += 2;
30 return (double)value / (double)value_max;
31 }
32
33 static double
34 get_value_u32(char** bufp)
35 {
36 uint32_t value = ntohl(*(uint32_t *)(*bufp));
37 *bufp += 4;
38 return (double)value / (double)value_max;
39 }
40
41 static double
42 get_value_u64(char** bufp)
43 {
44 uint64_t value;
45 value = (uint64_t)(buf[0]) << 56;
46 value |= (uint64_t)(buf[1]) << 48;
47 value |= (uint64_t)(buf[2]) << 40;
48 value |= (uint64_t)(buf[3]) << 32;
49 value |= (uint64_t)(buf[4]) << 24;
50 value |= (uint64_t)(buf[5]) << 16;
51 value |= (uint64_t)(buf[6]) << 8;
52 value |= (uint64_t)(buf[7]);
53 *bufp += 8;
54 return (double)value / (double)value_max;
55 }
56
57 static void
58 from_srgb(size_t n)
59 {
60 double red, green, blue, pixel[4];
61 size_t ptr;
62 char *p;
63 for (ptr = 0; ptr + pixel_size <= n; ptr += pixel_size) {
64 p = buf + ptr;
65 red = srgb_decode(get_value(&p));
66 green = with_colour ? srgb_decode(get_value(&p)) : re…
67 blue = with_colour ? srgb_decode(get_value(&p)) : re…
68 pixel[3] = with_alpha ? get_value(&p) : 1;
69 srgb_to_ciexyz(red, green, blue, pixel + 0, pixel + 1, p…
70 ewriteall(STDOUT_FILENO, pixel, sizeof(pixel), "<stdout>…
71 }
72 }
73
74 static size_t
75 farbfeld_head(int fd, const char *fname)
76 {
77 if (ereadall(fd, buf, 16, fname) != 16)
78 eprintf("%s\n", conv_fail_msg);
79 if (memcmp(buf, "farbfeld", 8))
80 eprintf("%s\n", conv_fail_msg);
81 sprintf(width, "%"PRIu32, ntohl(*(uint32_t *)(buf + 8)));
82 sprintf(height, "%"PRIu32, ntohl(*(uint32_t *)(buf + 12)));
83 pixel_size = 4 * sizeof(uint16_t);
84 value_max = UINT16_MAX;
85 get_value = get_value_u16;
86 convert = from_srgb;
87 return 0;
88 }
89
90 static size_t
91 pam_head(int fd, const char *fname)
92 {
93 size_t ptr;
94 size_t r;
95 char *p;
96 unsigned long long int maxval = UINT8_MAX;
97 for (ptr = 0;;) {
98 if (!(r = eread(fd, buf + ptr, sizeof(buf) - 1, fname)))
99 eprintf("%s\n", conv_fail_msg);
100 ptr += r;
101 for (;;) {
102 p = memchr(buf, '\n', ptr);
103 if (!p) {
104 if (ptr == sizeof(buf))
105 eprintf("%s\n", conv_fail_msg);
106 break;
107 }
108 *p++ = '\0';
109 if (strstr(buf, "WIDTH ") == buf) {
110 if (*width || !buf[6] || strlen(buf + 6)…
111 eprintf("%s\n", conv_fail_msg);
112 strcpy(width, buf + 6);
113 } else if (strstr(buf, "HEIGHT ") == buf) {
114 if (*height || !buf[7] || strlen(buf + 7…
115 eprintf("%s\n", conv_fail_msg);
116 strcpy(height, buf + 7);
117 } else if (strstr(buf, "MAXVAL ") == buf) {
118 if (tollu(buf + 7, 0, UINT64_MAX, &maxva…
119 if (errno != ERANGE)
120 eprintf("%s\n", conv_fai…
121 eprintf("image uses greater colo…
122 } else if (!maxval) {
123 eprintf("%s\n", conv_fail_msg);
124 }
125 } else if (strstr(buf, "TUPLTYPE ") == buf) {
126 if (!strcmp(buf, "TUPLTYPE BLACKANDWHITE…
127 maxval = 1, with_colour = 0, wit…
128 else if (!strcmp(buf, "TUPLTYPE BLACKAND…
129 maxval = 1, with_colour = 0, wit…
130 else if (!strcmp(buf, "TUPLTYPE GRAYSCAL…
131 with_colour = 0, with_alpha = 0;
132 else if (!strcmp(buf, "TUPLTYPE GRAYSCAL…
133 with_colour = 0, with_alpha = 1;
134 else if (!strcmp(buf, "TUPLTYPE RGB"))
135 with_colour = 1, with_alpha = 0;
136 else if (!strcmp(buf, "TUPLTYPE RGB_ALPH…
137 with_colour = 1, with_alpha = 1;
138 else
139 eprintf("image uses an unsupport…
140 } else if (!strcmp(buf, "ENDHDR")) {
141 memmove(buf, p, ptr -= (size_t)(p - buf)…
142 goto header_done;
143 }
144 memmove(buf, p, ptr -= (size_t)(p - buf));
145 }
146 }
147 header_done:
148 if (maxval <= (size_t)UINT8_MAX) {
149 pixel_size = sizeof(uint8_t);
150 get_value = get_value_u8;
151 } else if (maxval <= (size_t)UINT16_MAX) {
152 pixel_size = sizeof(uint16_t);
153 get_value = get_value_u16;
154 } else if (maxval <= (size_t)UINT32_MAX) {
155 pixel_size = sizeof(uint32_t);
156 get_value = get_value_u32;
157 } else {
158 pixel_size = sizeof(uint64_t);
159 get_value = get_value_u64;
160 }
161 value_max = (double)maxval;
162 pixel_size *= (size_t)((with_colour ? 3 : 1) + with_alpha);
163 convert = from_srgb;
164 return ptr;
165 }
166
167 int
168 main(int argc, char *argv[])
169 {
170 int status, pipe_rw[2], i, old_fd, forked = 0;
171 int headless = 0, farbfeld = 0, pam = 0;
172 pid_t pid = 0;
173 size_t off, n;
174 ssize_t r;
175 const char *file = "<subprocess>";
176
177 ARGBEGIN {
178 case 'f':
179 farbfeld = 1;
180 break;
181 case 'h':
182 headless = 1;
183 break;
184 case 'p':
185 pam = 1;
186 break;
187 default:
188 usage();
189 } ARGEND;
190
191 if (argc || (farbfeld && pam))
192 usage();
193
194 if (farbfeld)
195 conv_fail_msg = "not a valid farbfeld file, try without …
196 else if (pam)
197 conv_fail_msg = "not a valid RGBA portable arbitrary map…
198 else
199 forked = 1;
200
201 if (!forked) {
202 file = "<stdin>";
203 pipe_rw[0] = STDIN_FILENO;
204 goto after_fork;
205 }
206
207 epipe(pipe_rw);
208 if (pipe_rw[0] == STDIN_FILENO || pipe_rw[1] == STDIN_FILENO)
209 eprintf("no stdin open\n");
210 if (pipe_rw[0] == STDOUT_FILENO || pipe_rw[1] == STDOUT_FILENO)
211 eprintf("no stdout open\n");
212 for (i = 0; i < 2; i++) {
213 if (pipe_rw[i] == STDERR_FILENO) {
214 pipe_rw[i] = edup(old_fd = pipe_rw[i]);
215 close(old_fd);
216 }
217 }
218
219 pid = efork();
220 if (!pid) {
221 close(pipe_rw[0]);
222 edup2(pipe_rw[1], STDOUT_FILENO);
223 close(pipe_rw[1]);
224 /* XXX Is there a way to convert directly to raw XYZ? (W…
225 eexeclp("convert", "convert", "-", "-depth", "32", "-alp…
226 }
227
228 close(pipe_rw[1]);
229 after_fork:
230
231 if (farbfeld)
232 n = farbfeld_head(pipe_rw[0], file);
233 else
234 n = pam_head(pipe_rw[0], file);
235
236 if (!*width || !*height)
237 eprintf("%s\n", conv_fail_msg);
238
239 if (!headless) {
240 FPRINTF_HEAD_FMT(stdout, "%i", 1, "%s", width, "%s", hei…
241 efflush(stdout, "<stdout>");
242 }
243
244 for (;;) {
245 convert(n);
246 off = n - (n % pixel_size);
247 memmove(buf, buf + off, n -= off);
248 r = read(pipe_rw[0], buf + n, sizeof(buf) - n);
249 if (r < 0)
250 eprintf("read %s:", file);
251 if (r == 0)
252 break;
253 n += (size_t)r;
254 }
255
256 if (!forked)
257 return 0;
258 close(pipe_rw[0]);
259 while (waitpid(pid, &status, 0) != pid);
260 return !!status;
261 }
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.