blind-crop.c - blind - suckless command-line video editing utility
(HTM) git clone git://git.suckless.org/blind
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) 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 : height * orown;
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) * irown;
74 for (x = 0; x < irown; x++, ptr++)
75 image[ptr] = p[(x + off) % orown + left];
76 }
77 } else if (keepsize) {
78 memset(image, 0, top * irown);
79 memset(image + bottom_start * irown, 0, bottom * irown);
80 for (y = top; y < bottom_start; y++) {
81 memset(image + y * irown, 0, left);
82 memset(image + y * irown + right_start, 0, right);
83 }
84 } else if (keepsize_inv) {
85 for (y = top; y < bottom_start; y++)
86 memset(image + y * irown + left, 0, orown);
87 } else {
88 for (y = 0; y < height; y++)
89 memcpy(image + y * orown, buf + y * irown + off, orown);
90 }
91 ewriteall(STDOUT_FILENO, image, m, "<stdout>");
92 }
93
94 if (buf != image)
95 free(image);
96 free(buf);
97 return 0;
98 }