blind

suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log | Files | Refs | README | LICENSE

blind-mosaic-edges.c (2755B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include "common.h"
      3 
      4 USAGE("[-xy]")
      5 
      6 int
      7 main(int argc, char *argv[])
      8 {
      9 	int tiled_x = 0;
     10 	int tiled_y = 0;
     11 	struct stream stream;
     12 	void *colours[2];
     13 	char *buf, *edges, *here;
     14 	size_t i, n, x, y;
     15 	int v;
     16 
     17 	ARGBEGIN {
     18 	case 'x':
     19 		tiled_x = 1;
     20 		break;
     21 	case 'y':
     22 		tiled_y = 1;
     23 		break;
     24 	default:
     25 		usage();
     26 	} ARGEND;
     27 
     28 	if (argc)
     29 		usage();
     30 
     31 	eopen_stream(&stream, NULL);
     32 	echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
     33 
     34 	n = stream.width * stream.height;
     35 	buf = emalloc(stream.frame_size);
     36 	edges = emalloc((n + 7) / 8);
     37 
     38 	colours[0] = alloca(stream.pixel_size);
     39 	colours[1] = alloca(stream.pixel_size);
     40 	memset(colours[0], 0, stream.pixel_size);
     41 
     42 	if (stream.encoding == DOUBLE) {
     43 		((double *)(colours[1]))[0] = (double)1;
     44 		((double *)(colours[1]))[1] = (double)1;
     45 		((double *)(colours[1]))[2] = (double)1;
     46 		((double *)(colours[1]))[3] = (double)1;
     47 	} else if (stream.encoding == FLOAT) {
     48 		((float *)(colours[1]))[0] = (float)1;
     49 		((float *)(colours[1]))[1] = (float)1;
     50 		((float *)(colours[1]))[2] = (float)1;
     51 		((float *)(colours[1]))[3] = (float)1;
     52 	} else {
     53 		eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
     54 	}
     55 
     56 	fprint_stream_head(stdout, &stream);
     57 	efflush(stdout, "<stdout>");
     58 
     59 	while (eread_frame(&stream, buf)) {
     60 		memset(edges, 0, (n + 7) / 8);
     61 		for (i = 0; i < n; i++) {
     62 			here = buf + i * stream.pixel_size;
     63 			x = i % stream.width;
     64 			y = i / stream.width;
     65 
     66 			if (x != stream.width - 1) {
     67 				if (memcmp(here + stream.pixel_size, here, stream.pixel_size))
     68 					goto at_edge;
     69 			} else if (tiled_x) {
     70 				if (memcmp(here + stream.pixel_size - stream.row_size, here, stream.pixel_size))
     71 					goto at_edge;
     72 			}
     73 
     74 			if (x) {
     75 				if (memcmp(here - stream.pixel_size, here, stream.pixel_size))
     76 					goto at_edge;
     77 			} else if (tiled_x) {
     78 				if (memcmp(here + stream.row_size - stream.pixel_size, here, stream.pixel_size))
     79 					goto at_edge;
     80 			}
     81 
     82 			if (y != stream.height - 1) {
     83 				if (memcmp(here + stream.row_size, here, stream.pixel_size))
     84 					goto at_edge;
     85 			} else if (tiled_y) {
     86 				if (memcmp(here + stream.row_size - stream.frame_size, here, stream.pixel_size))
     87 					goto at_edge;
     88 			}
     89 
     90 			if (y) {
     91 				if (memcmp(here - stream.row_size, here, stream.pixel_size))
     92 					goto at_edge;
     93 			} else if (tiled_y) {
     94 				if (memcmp(here + stream.frame_size - stream.row_size, here, stream.pixel_size))
     95 					goto at_edge;
     96 			}
     97 
     98 			continue;
     99 		at_edge:
    100 			edges[i >> 3] |= (char)(1 << (i & 7));
    101 		}
    102 		for (i = 0; i < n; i++) {
    103 			v = (edges[i >> 3] >> (i & 7)) & 1;
    104 			memcpy(buf + i * stream.pixel_size, colours[v], stream.pixel_size);
    105 		}
    106 		ewriteall(STDOUT_FILENO, buf, stream.frame_size, "<stdout>");
    107 	}
    108 
    109 	free(buf);
    110 	free(edges);
    111 	return 0;
    112 }