blind-crop.c - blind - suckless command-line video editing utility | |
git clone git://git.suckless.org/blind | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
blind-crop.c (2796B) | |
--- | |
1 /* See LICENSE file for copyright and license details. */ | |
2 #include "common.h" | |
3 | |
4 USAGE("[-s | -S | -t] width height left top") | |
5 | |
6 int | |
7 main(int argc, char *argv[]) | |
8 { | |
9 struct stream stream; | |
10 char *buf, *image, *p; | |
11 size_t width = 0, height = 0, left = 0, top = 0; | |
12 size_t right, right_start, bottom, bottom_start; | |
13 size_t off, yoff = 0, x, y, irown, orown, ptr, m; | |
14 int tile = 0, keepsize = 0, keepsize_inv = 0; | |
15 | |
16 ARGBEGIN { | |
17 case 's': | |
18 keepsize = 1; | |
19 break; | |
20 case 'S': | |
21 keepsize_inv = 1; | |
22 break; | |
23 case 't': | |
24 tile = 1; | |
25 break; | |
26 default: | |
27 usage(); | |
28 } ARGEND; | |
29 | |
30 if (argc != 4 || tile + keepsize + keepsize_inv > 1) | |
31 usage(); | |
32 | |
33 width = etozu_arg("the width", argv[0], 1, SIZE_MAX); | |
34 height = etozu_arg("the height", argv[1], 1, SIZE_MAX); | |
35 left = etozu_arg("the left position", argv[2], 0, SIZE_MAX); | |
36 top = etozu_arg("the top position", argv[3], 0, SIZE_MAX); | |
37 | |
38 eopen_stream(&stream, NULL); | |
39 if (left > SIZE_MAX - width || left + width > stream.width || | |
40 top > SIZE_MAX - height || top + height > stream.height) | |
41 eprintf("crop area extends beyond original image\n"); | |
42 if (tile || keepsize || keepsize_inv) { | |
43 fprint_stream_head(stdout, &stream); | |
44 } else { | |
45 x = stream.width, stream.width = width; | |
46 y = stream.height, stream.height = height; | |
47 fprint_stream_head(stdout, &stream); | |
48 stream.width = x; | |
49 stream.height = y; | |
50 } | |
51 efflush(stdout, "<stdout>"); | |
52 | |
53 echeck_dimensions(&stream, WIDTH | HEIGHT, NULL); | |
54 irown = stream.row_size; | |
55 buf = emalloc(stream.frame_size); | |
56 orown = width * stream.pixel_size; | |
57 m = (tile || keepsize || keepsize_inv) ? stream.frame_size : hei… | |
58 image = (keepsize || keepsize_inv) ? buf : emalloc(m); | |
59 | |
60 left *= stream.pixel_size; | |
61 if (!tile) { | |
62 off = top * irown + left; | |
63 } else { | |
64 off = (orown - left % orown) % orown; | |
65 yoff = (height - top % height) % height; | |
66 } | |
67 bottom = stream.height - (bottom_start = top + height); | |
68 right = irown - (right_start = left + orown); | |
69 | |
70 while (eread_frame(&stream, buf)) { | |
71 if (tile) { | |
72 for (ptr = y = 0; y < stream.height; y++) { | |
73 p = buf + ((y + yoff) % height + top) * … | |
74 for (x = 0; x < irown; x++, ptr++) | |
75 image[ptr] = p[(x + off) % orown… | |
76 } | |
77 } else if (keepsize) { | |
78 memset(image, 0, top * irown); | |
79 memset(image + bottom_start * irown, 0, bottom *… | |
80 for (y = top; y < bottom_start; y++) { | |
81 memset(image + y * irown, 0, left); | |
82 memset(image + y * irown + right_start, … | |
83 } | |
84 } else if (keepsize_inv) { | |
85 for (y = top; y < bottom_start; y++) | |
86 memset(image + y * irown + left, 0, orow… | |
87 } else { | |
88 for (y = 0; y < height; y++) | |
89 memcpy(image + y * orown, buf + y * irow… | |
90 } | |
91 ewriteall(STDOUT_FILENO, image, m, "<stdout>"); | |
92 } | |
93 | |
94 if (buf != image) | |
95 free(image); | |
96 free(buf); | |
97 return 0; | |
98 } |