blind

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

blind-spectrum.c (4885B)


      1 /* See LICENSE file for copyright and license details. */
      2 #ifndef TYPE
      3 #include "common.h"
      4 
      5 USAGE("[-y] [-z depth] spectrum-stream")
      6 
      7 static int luma = 0;
      8 static size_t nz = 1;
      9 
     10 #define FILE "blind-spectrum.c"
     11 #include "define-functions.h"
     12 
     13 int
     14 main(int argc, char *argv[])
     15 {
     16 	struct stream stream, spectrum;
     17 	void (*process)(struct stream *stream, struct stream *spectrum);
     18 
     19 	ARGBEGIN {
     20 	case 'y':
     21 		luma = 1;
     22 		break;
     23 	case 'z':
     24 		nz = etozu_flag('z', UARGF(), 1, SIZE_MAX);
     25 		break;
     26 	default:
     27 		usage();
     28 	} ARGEND;
     29 
     30 	if (argc != 1)
     31 		usage();
     32 
     33 	eopen_stream(&stream, NULL);
     34 	eopen_stream(&spectrum, argv[0]);
     35 
     36 	SELECT_PROCESS_FUNCTION(&stream);
     37 	CHECK_CHANS(&stream, == 3, == (luma ? 1 : stream.luma_chan));
     38 	CHECK_N_CHAN(&stream, 4, 4);
     39 
     40 	if (stream.n_chan != spectrum.n_chan || stream.encoding != spectrum.encoding)
     41 		eprintf("videos use incompatible pixel formats\n");
     42 
     43 	echeck_dimensions(&spectrum, WIDTH | HEIGHT, "spectrum");
     44 
     45 	fprint_stream_head(stdout, &stream);
     46 	efflush(stdout, "<stdout>");
     47 	process(&stream, &spectrum);
     48 	return 0;
     49 }
     50 
     51 #else
     52 
     53 static void
     54 PROCESS(struct stream *stream, struct stream *spectrum)
     55 {
     56 	TYPE *table = emalloc2(nz, spectrum->frame_size);
     57 	size_t i, n, m = 0;
     58 	TYPE x, y, z, a, x1, y1, z1, a1, x2, y2, z2, a2, ix, iy, iz, wx, wy, wz;
     59 	size_t s, t, nx, ny, nxy;
     60 	nx = spectrum->width;
     61 	ny = spectrum->height;
     62 	nxy = nx * ny;
     63 	if (luma)
     64 		ny = nxy * nz;
     65 	do {
     66 		if (!m) {
     67 			m = stream->frame_size;
     68 			for (i = 0; i < nz; i++) {
     69 				if (!eread_frame(spectrum, ((char *)table) + i * spectrum->frame_size)) {
     70 					if (!i)
     71 						goto done;
     72 					eprintf("%s: incomplete frame set\n", spectrum->file);
     73 				}
     74 			}
     75 		}
     76 		n = MIN(stream->ptr, m) / stream->pixel_size;
     77 		for (i = 0; i < n; i++) {
     78 			if (luma) {
     79 				iy = ((TYPE *)(stream->buf))[4 * i + 1];
     80 				iy = MIN(MAX(iy, (TYPE)0), (TYPE)1);
     81 				iy *= (TYPE)(ny - 1);
     82 				s = (size_t)iy;
     83 				t = s + 1;
     84 				t = t == ny ? ny - 1 : t;
     85 				wy = mod(iy, (TYPE)1);
     86 				x = table[4 * s + 0] * (1 - wy) + table[4 * t + 0] * wy;
     87 				y = table[4 * s + 1] * (1 - wy) + table[4 * t + 1] * wy;
     88 				z = table[4 * s + 2] * (1 - wy) + table[4 * t + 2] * wy;
     89 				a = table[4 * s + 3] * (1 - wy) + table[4 * t + 3] * wy;
     90 			} else {
     91 				ix = ((TYPE *)(stream->buf))[4 * i + 0];
     92 				iy = ((TYPE *)(stream->buf))[4 * i + 1];
     93 				iz = ((TYPE *)(stream->buf))[4 * i + 2];
     94 				ix = MIN(MAX(ix, (TYPE)0), (TYPE)1);
     95 				iy = MIN(MAX(iy, (TYPE)0), (TYPE)1);
     96 				iz = MIN(MAX(iz, (TYPE)0), (TYPE)1);
     97 				ix *= (TYPE)(nx - 1);
     98 				iy *= (TYPE)(ny - 1);
     99 				iz *= (TYPE)(nz - 1);
    100 				wx = mod(ix, (TYPE)1);
    101 				wy = mod(iy, (TYPE)1);
    102 				wz = mod(iz, (TYPE)1);
    103 				s = (size_t)ix;
    104 				t = s + 1;
    105 				t = t == nx ? nx - 1 : t;
    106 				s += (size_t)iy * nx;
    107 				t += (size_t)iy * nx;
    108 				s += (size_t)iz * nxy;
    109 				t += (size_t)iz * nxy;
    110 				x = table[4 * s + 0] * (1 - wx) + table[4 * t + 0] * wx;
    111 				y = table[4 * s + 1] * (1 - wx) + table[4 * t + 1] * wx;
    112 				z = table[4 * s + 2] * (1 - wx) + table[4 * t + 2] * wx;
    113 				a = table[4 * s + 3] * (1 - wx) + table[4 * t + 3] * wx;
    114 				if ((size_t)iy != ny - 1) {
    115 					s += nx, t += nx;
    116 					x2 = table[4 * s + 0] * (1 - wx) + table[4 * t + 0] * wx;
    117 					y2 = table[4 * s + 1] * (1 - wx) + table[4 * t + 1] * wx;
    118 					z2 = table[4 * s + 2] * (1 - wx) + table[4 * t + 2] * wx;
    119 					a2 = table[4 * s + 3] * (1 - wx) + table[4 * t + 3] * wx;
    120 					x = x * (1 - wy) + x2 * wy;
    121 					y = y * (1 - wy) + y2 * wy;
    122 					z = z * (1 - wy) + z2 * wy;
    123 					a = a * (1 - wy) + a2 * wy;
    124 					s -= nx, t -= nx;
    125 				}
    126 				if ((size_t)iz != nz - 1) {
    127 					s += nxy, t += nxy;
    128 					x1 = table[4 * s + 0] * (1 - wx) + table[4 * t + 0] * wx;
    129 					y1 = table[4 * s + 1] * (1 - wx) + table[4 * t + 1] * wx;
    130 					z1 = table[4 * s + 2] * (1 - wx) + table[4 * t + 2] * wx;
    131 					a1 = table[4 * s + 3] * (1 - wx) + table[4 * t + 3] * wx;
    132 					if ((size_t)iy != ny - 1) {
    133 						s += nx, t += nx;
    134 						x2 = table[4 * s + 0] * (1 - wx) + table[4 * t + 0] * wx;
    135 						y2 = table[4 * s + 1] * (1 - wx) + table[4 * t + 1] * wx;
    136 						z2 = table[4 * s + 2] * (1 - wx) + table[4 * t + 2] * wx;
    137 						a2 = table[4 * s + 3] * (1 - wx) + table[4 * t + 3] * wx;
    138 						x1 = x1 * (1 - wy) + x2 * wy;
    139 						y1 = y1 * (1 - wy) + y2 * wy;
    140 						z1 = z1 * (1 - wy) + z2 * wy;
    141 						a1 = a1 * (1 - wy) + a2 * wy;
    142 					}
    143 					x = x * (1 - wz) + x1 * wz;
    144 					y = y * (1 - wz) + y1 * wz;
    145 					z = z * (1 - wz) + z1 * wz;
    146 					a = a * (1 - wz) + a1 * wz;
    147 				}
    148 			}
    149 			((TYPE *)(stream->buf))[4 * i + 0] = x;
    150 			((TYPE *)(stream->buf))[4 * i + 1] = y;
    151 			((TYPE *)(stream->buf))[4 * i + 2] = z;
    152 			((TYPE *)(stream->buf))[4 * i + 3] *= a;
    153 		}
    154 		n *= stream->pixel_size;
    155 		m -= n;
    156 		ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");
    157 		memmove(stream->buf, stream->buf + n, stream->ptr -= n);
    158 	} while (eread_stream(stream, SIZE_MAX));
    159 	if (stream->ptr)
    160 		eprintf("%s: incomplete frame\n", stream->file);
    161 done:
    162 	free(table);
    163 }
    164 
    165 #endif