Introduction
Introduction Statistics Contact Development Disclaimer Help
blind-find-rectangle.c - blind - suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log
Files
Refs
README
LICENSE
---
blind-find-rectangle.c (3127B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include "common.h"
3
4 USAGE("[-a min-area] [-h min-height] [-w min-width] X Y Z [alpha]")
5
6 struct pair {
7 size_t x;
8 size_t w;
9 };
10
11 static struct stream stream;
12 static size_t min_width = 1;
13 static size_t min_height = 1;
14 static size_t min_area = 1;
15 static struct pair *stack = NULL;
16 static size_t *cache = NULL;
17 static char *buf = NULL;
18
19 static void
20 process(const void *colour)
21 {
22 size_t y, x, x0, w, w0, h, top, area;
23 size_t best_area, x1, x2, y1, y2;
24 for (;;) {
25 top = x1 = x2 = y1 = y2 = best_area = 0;
26 memset(cache, 0, (stream.width + 1) * sizeof(*cache));
27 for (y = 0; eread_row(&stream, buf); y++) {
28 w = 0;
29 for (x = 0; x <= stream.width; x++) {
30 if (x != stream.width) {
31 if (!memcmp(buf + x * stream.pix…
32 cache[x] += 1;
33 else
34 cache[x] = 0;
35 }
36 if (cache[x] > w) {
37 stack[top].x = x;
38 stack[top++].w = w;
39 w = cache[x];
40 } else if (cache[x] < w) {
41 do {
42 x0 = stack[--top].x;
43 w0 = stack[top].w;
44 area = w * (x - x0);
45 if (area > best_area) {
46 best_area = area;
47 x1 = x0;
48 x2 = x - 1;
49 y1 = y - w + 1;
50 y2 = y;
51 }
52 w = w0;
53 } while (cache[x] < w);
54 if ((w = cache[x])) {
55 stack[top].x = x0;
56 stack[top++].w = w0;
57 }
58 }
59 }
60 fprintf(stderr, "%zu\n", y);
61 }
62 if (!y)
63 break;
64 w = x2 - x1 + 1;
65 h = y2 - y1 + 1;
66 if (best_area < min_area || w < min_width || h < min_hei…
67 printf("0 0 0 0\n");
68 else
69 printf("%zu %zu %zu %zu\n", x1, y1, w, h);
70 }
71 }
72
73 int
74 main(int argc, char *argv[])
75 {
76 double colour_lf[4];
77 float colour_f[4];
78 double X, Y, Z, alpha = 1;
79
80 ARGBEGIN {
81 case 'a':
82 min_area = etozu_flag('a', UARGF(), 1, SIZE_MAX);
83 break;
84 case 'h':
85 min_height = etozu_flag('h', UARGF(), 1, SIZE_MAX);
86 break;
87 case 'w':
88 min_width = etozu_flag('w', UARGF(), 1, SIZE_MAX);
89 break;
90 default:
91 usage();
92 } ARGEND;
93
94 if (argc != 3 && argc != 4)
95 usage();
96
97 X = etolf_arg("the X value", argv[0]);
98 Y = etolf_arg("the Y value", argv[1]);
99 Z = etolf_arg("the Z value", argv[2]);
100 if (argc > 3)
101 alpha = etolf_arg("the alpha value", argv[3]);
102
103 eopen_stream(&stream, NULL);
104 echeck_dimensions(&stream, WIDTH, NULL);
105 if (stream.width == SIZE_MAX)
106 eprintf("video is too wide\n");
107 if (stream.width > SIZE_MAX / stream.height)
108 eprintf("video is too large\n");
109
110 stack = emalloc2(stream.width + 1, sizeof(*stack));
111 cache = emalloc2(stream.width + 1, sizeof(*cache));
112 buf = emalloc(stream.row_size);
113
114 if (argc > 3)
115 CHECK_ALPHA(&stream);
116 CHECK_N_CHAN(&stream, 1, 3 + !!stream.alpha);
117 if (stream.encoding == DOUBLE) {
118 colour_lf[0] = X;
119 colour_lf[1] = Y;
120 colour_lf[2] = Z;
121 colour_lf[3] = alpha;
122 process(colour_lf);
123 } else if (stream.encoding == FLOAT) {
124 colour_f[0] = (float)X;
125 colour_f[1] = (float)Y;
126 colour_f[2] = (float)Z;
127 colour_f[3] = (float)alpha;
128 process(colour_f);
129 } else {
130 eprintf("pixel format %s is not supported, try xyza\n", …
131 }
132
133 fshut(stdout, "<stdout>");
134 free(stack);
135 free(cache);
136 free(buf);
137 return 0;
138 }
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.