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 }