commit 29716cb446111a6c0d82df08d18a1eec848d826c
parent 53b325340554af869cdc619b2b93ccfbaa33ba0c
Author: Mattias Andrée <maandree@kth.se>
Date: Sun, 29 Jan 2017 20:35:26 +0100
blind-crop: add -s and -S
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat:
2 files changed, 44 insertions(+), 12 deletions(-)
diff --git a/man/blind-crop.1 b/man/blind-crop.1
@@ -3,7 +3,7 @@
blind-crop - Extract subframes for all frames
.SH SYNOPSIS
.B blind-crop
-[-t]
+[-s | -S | -t]
.I width
.I height
.I left
@@ -30,6 +30,16 @@ The selected subvideo may not extend beyond the
input video.
.SH OPTIONS
.TP
+.B -s
+Instead of resizing the video, set alpha (and
+all colour parameters) to 0 on each pixel outside
+the selected region.
+.TP
+.B -S
+Instead of resizing the video, set alpha (and
+all colour parameters) to 0 on each pixel inside
+the selected region.
+.TP
.B -t
Instead of changing the width and height of
the output video, put the subvideo side-by-side.
diff --git a/src/blind-crop.c b/src/blind-crop.c
@@ -7,7 +7,7 @@
#include <string.h>
#include <unistd.h>
-USAGE("[-t] width height left top")
+USAGE("[-s | -S | -t] width height left top")
int
main(int argc, char *argv[])
@@ -15,10 +15,17 @@ main(int argc, char *argv[])
struct stream stream;
char *buf, *image, *p;
size_t width = 0, height = 0, left = 0, top = 0;
+ size_t right, right_start, bottom, bottom_start;
size_t off, yoff = 0, x, y, irown, orown, ptr, n, m;
- int tile = 0;
+ int tile = 0, keepsize = 0, keepsize_inv = 0;
ARGBEGIN {
+ case 's':
+ keepsize = 1;
+ break;
+ case 'S':
+ keepsize_inv = 1;
+ break;
case 't':
tile = 1;
break;
@@ -26,7 +33,7 @@ main(int argc, char *argv[])
usage();
} ARGEND;
- if (argc != 4)
+ if (argc != 4 || tile + keepsize + keepsize_inv > 1)
usage();
width = etozu_arg("the width", argv[0], 1, SIZE_MAX);
@@ -40,7 +47,7 @@ main(int argc, char *argv[])
if (left > SIZE_MAX - width || left + width > stream.width ||
top > SIZE_MAX - height || top + height > stream.height)
eprintf("crop area extends beyond original image\n");
- if (tile) {
+ if (tile || keepsize || keepsize_inv) {
fprint_stream_head(stdout, &stream);
} else {
x = stream.width, stream.width = width;
@@ -55,8 +62,8 @@ main(int argc, char *argv[])
n = stream.height * (irown = stream.width * stream.pixel_size);
buf = emalloc(n);
orown = width * stream.pixel_size;
- m = tile ? n : height * orown;
- image = emalloc(m);
+ m = (tile || keepsize || keepsize_inv) ? n : height * orown;
+ image = (keepsize || keepsize_inv) ? buf : malloc(m);
left *= stream.pixel_size;
if (!tile) {
@@ -65,23 +72,38 @@ main(int argc, char *argv[])
off = (orown - left % orown) % orown;
yoff = (height - top % height) % height;
}
+ bottom_start = top + height;
+ bottom = stream.height - bottom_start;
+ right_start = left + orown;
+ right = irown - right_start;
memcpy(buf, stream.buf, ptr = stream.ptr);
while (eread_frame(&stream, buf, n)) {
- if (!tile) {
- for (y = 0; y < height; y++)
- memcpy(image + y * orown, buf + y * irown + off, orown);
- } else {
+ if (tile) {
for (ptr = y = 0; y < stream.height; y++) {
p = buf + ((y + yoff) % height + top) * irown;
for (x = 0; x < irown; x++, ptr++)
image[ptr] = p[(x + off) % orown + left];
}
+ } else if (keepsize) {
+ memset(image, 0, top * irown);
+ memset(image + bottom_start * irown, 0, bottom * irown);
+ for (y = top; y < bottom_start; y++) {
+ memset(image + y * irown, 0, left);
+ memset(image + y * irown + right_start, 0, right);
+ }
+ } else if (keepsize_inv) {
+ for (y = top; y < bottom_start; y++)
+ memset(image + y * irown + left, 0, orown);
+ } else {
+ for (y = 0; y < height; y++)
+ memcpy(image + y * orown, buf + y * irown + off, orown);
}
ewriteall(STDOUT_FILENO, image, m, "<stdout>");
}
+ if (buf != image)
+ free(image);
free(buf);
- free(image);
return 0;
}