commit 29716cb446111a6c0d82df08d18a1eec848d826c
Author:     Mattias Andrée <[email protected]>
AuthorDate: Sun Jan 29 20:35:26 2017 +0100
Commit:     Mattias Andrée <[email protected]>
CommitDate: Sun Jan 29 20:35:26 2017 +0100

    blind-crop: add -s and -S
    
    Signed-off-by: Mattias Andrée <[email protected]>

diff --git a/man/blind-crop.1 b/man/blind-crop.1
index df51df9..8e2a34e 100644
--- 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
index f45875e..bd0b9e0 100644
--- 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;
 }

Reply via email to