blind

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

blind-split-chans.c (2876B)


      1 /* See LICENSE file for copyright and license details. */
      2 #include "common.h"
      3 
      4 USAGE("[-c] X-file Y-file Z-file [alpha-file]")
      5 
      6 int
      7 main(int argc, char *argv[])
      8 {
      9 	struct stream stream;
     10 	char xbuf[sizeof(stream.buf)], ybuf[sizeof(xbuf)], zbuf[sizeof(xbuf)], abuf[sizeof(xbuf)];
     11 	int xfd, yfd, zfd, afd = -1;
     12 	size_t i, n, ptr, cs;
     13 	int all_channels = 1;
     14 
     15 	ARGBEGIN {
     16 	case 'c':
     17 		all_channels = 0;
     18 		break;
     19 	default:
     20 		usage();
     21 	} ARGEND;
     22 
     23 	if (argc != 3 && argc != 4)
     24 		usage();
     25 
     26 	eopen_stream(&stream, NULL);
     27 	CHECK_ALPHA_CHAN(&stream);
     28 	CHECK_N_CHAN(&stream, 4, 4);
     29 
     30 	xfd = eopen(argv[0], O_WRONLY | O_CREAT | O_TRUNC, 0666);
     31 	yfd = eopen(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0666);
     32 	zfd = eopen(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666);
     33 	if (argc == 4)
     34 		afd = eopen(argv[3], O_WRONLY | O_CREAT | O_TRUNC, 0666);
     35 
     36 	if (DPRINTF_HEAD(xfd, stream.frames, stream.width, stream.height, stream.pixfmt) < 0)
     37 		eprintf("dprintf %s:", argv[0]);
     38 	if (DPRINTF_HEAD(yfd, stream.frames, stream.width, stream.height, stream.pixfmt) < 0)
     39 		eprintf("dprintf %s:", argv[1]);
     40 	if (DPRINTF_HEAD(zfd, stream.frames, stream.width, stream.height, stream.pixfmt) < 0)
     41 		eprintf("dprintf %s:", argv[2]);
     42 	if (afd >= 0 && DPRINTF_HEAD(afd, stream.frames, stream.width, stream.height, stream.pixfmt) < 0)
     43 		eprintf("dprintf %s:", argv[3]);
     44 
     45 	if (!all_channels) {
     46 		memset(xbuf, 0, sizeof(xbuf));
     47 		memset(ybuf, 0, sizeof(ybuf));
     48 		memset(zbuf, 0, sizeof(zbuf));
     49 		memset(abuf, 0, sizeof(abuf));
     50 	}
     51 
     52 	cs = stream.chan_size;
     53 	n = (stream.n_chan - (afd < 0)) * cs;
     54 	do {
     55 		for (ptr = 0; ptr + stream.pixel_size <= stream.ptr; ptr += stream.pixel_size) {
     56 			if (all_channels) {
     57 				for (i = 0; i < n; i += cs) {
     58 					memcpy(xbuf + ptr + i, stream.buf + ptr + 0 * cs, cs);
     59 					memcpy(ybuf + ptr + i, stream.buf + ptr + 1 * cs, cs);
     60 					memcpy(zbuf + ptr + i, stream.buf + ptr + 2 * cs, cs);
     61 					if (afd >= 0)
     62 						memcpy(abuf + ptr + i, stream.buf + ptr + 3 * cs, cs);
     63 				}
     64 			} else {
     65 				memcpy(xbuf + ptr + 0 * cs, stream.buf + ptr + 0 * cs, cs);
     66 				memcpy(ybuf + ptr + 1 * cs, stream.buf + ptr + 1 * cs, cs);
     67 				memcpy(zbuf + ptr + 2 * cs, stream.buf + ptr + 2 * cs, cs);
     68 				if (afd >= 0)
     69 					memcpy(abuf + ptr + 3 * cs, stream.buf + ptr + 3 * cs, cs);
     70 			}
     71 			if (afd < 0) {
     72 				memcpy(xbuf + ptr + n, stream.buf + ptr + 3 * cs, cs);
     73 				memcpy(ybuf + ptr + n, stream.buf + ptr + 3 * cs, cs);
     74 				memcpy(zbuf + ptr + n, stream.buf + ptr + 3 * cs, cs);
     75 			}
     76 		}
     77 		ewriteall(xfd, xbuf, ptr, argv[0]);
     78 		ewriteall(yfd, ybuf, ptr, argv[1]);
     79 		ewriteall(zfd, zbuf, ptr, argv[2]);
     80 		if (afd >= 0)
     81 			ewriteall(afd, abuf, ptr, argv[3]);
     82 		memmove(stream.buf, stream.buf + ptr, stream.ptr -= ptr);
     83 	} while (eread_stream(&stream, SIZE_MAX));
     84 	if (stream.ptr)
     85 		eprintf("%s: incomplete frame\n", stream.file);
     86 
     87 	close(xfd);
     88 	close(yfd);
     89 	close(zfd);
     90 	if (afd >= 0)
     91 		close(afd);
     92 	return 0;
     93 }