blind

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

commit b221dcb4c68b492d810f249959a0bd3322dbcdeb
parent 187994906ae77986072050ea2024fb531747fea5
Author: Mattias Andrée <maandree@kth.se>
Date:   Sat,  8 Jul 2017 00:51:57 +0200

Add blind-spectrum (not yet documented)

Signed-off-by: Mattias Andrée <maandree@kth.se>

Diffstat:
Makefile | 1+
src/blind-spectrum.c | 166+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 167 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile @@ -55,6 +55,7 @@ BIN =\ blind-sinc-wave\ blind-sine-wave\ blind-skip-pattern\ + blind-spectrum\ blind-spiral-gradient\ blind-split\ blind-split-cols\ diff --git a/src/blind-spectrum.c b/src/blind-spectrum.c @@ -0,0 +1,166 @@ +/* See LICENSE file for copyright and license details. */ +#include "common.h" + +USAGE("[-y] [-z depth] spectrum-stream") + +static int luma = 0; +static size_t nz = 1; + + +#define PROCESS(TYPE, SUFFIX)\ + static void\ + process_##SUFFIX(struct stream *stream, struct stream *spectrum)\ + {\ + TYPE *table = emalloc2(nz, spectrum->frame_size);\ + size_t i, n, m = 0;\ + TYPE x, y, z, a, x1, y1, z1, a1, x2, y2, z2, a2, ix, iy, iz, wx, wy, wz;\ + size_t s, t, nx, ny, nxy;\ + nx = spectrum->width;\ + ny = spectrum->height;\ + nxy = nx * ny;\ + if (luma)\ + ny = nxy * nz;\ + do {\ + if (!m) {\ + m = stream->frame_size;\ + for (i = 0; i < nz; i++) {\ + if (!eread_frame(spectrum, ((char *)table) + i * spectrum->frame_size)) {\ + if (!i)\ + goto done;\ + eprintf("%s: incomplete frame set\n", spectrum->file);\ + }\ + }\ + }\ + n = MIN(stream->ptr, m) / stream->pixel_size;\ + for (i = 0; i < n; i++) {\ + if (luma) {\ + iy = ((TYPE *)(stream->buf))[4 * i + 1];\ + iy = MIN(MAX(iy, (TYPE)0), (TYPE)1);\ + iy *= (TYPE)(ny - 1);\ + s = (size_t)iy;\ + t = s + 1;\ + t = t == ny ? ny - 1 : t;\ + wy = mod(iy, (TYPE)1);\ + x = table[4 * s + 0] * (1 - wy) + table[4 * t + 0] * wy;\ + y = table[4 * s + 1] * (1 - wy) + table[4 * t + 1] * wy;\ + z = table[4 * s + 2] * (1 - wy) + table[4 * t + 2] * wy;\ + a = table[4 * s + 3] * (1 - wy) + table[4 * t + 3] * wy;\ + } else {\ + ix = ((TYPE *)(stream->buf))[4 * i + 0];\ + iy = ((TYPE *)(stream->buf))[4 * i + 1];\ + iz = ((TYPE *)(stream->buf))[4 * i + 2];\ + ix = MIN(MAX(ix, (TYPE)0), (TYPE)1);\ + iy = MIN(MAX(iy, (TYPE)0), (TYPE)1);\ + iz = MIN(MAX(iz, (TYPE)0), (TYPE)1);\ + ix *= (TYPE)(nx - 1);\ + iy *= (TYPE)(ny - 1);\ + iz *= (TYPE)(nz - 1);\ + wx = mod(ix, (TYPE)1);\ + wy = mod(iy, (TYPE)1);\ + wz = mod(iz, (TYPE)1);\ + s = (size_t)ix;\ + t = s + 1;\ + t = t == nx ? nx - 1 : t;\ + s += (size_t)iy * nx;\ + t += (size_t)iy * nx;\ + s += (size_t)iz * nxy;\ + t += (size_t)iz * nxy;\ + x = table[4 * s + 0] * (1 - wx) + table[4 * t + 0] * wx;\ + y = table[4 * s + 1] * (1 - wx) + table[4 * t + 1] * wx;\ + z = table[4 * s + 2] * (1 - wx) + table[4 * t + 2] * wx;\ + a = table[4 * s + 3] * (1 - wx) + table[4 * t + 3] * wx;\ + if ((size_t)iy != ny - 1) {\ + s += nx, t += nx;\ + x2 = table[4 * s + 0] * (1 - wx) + table[4 * t + 0] * wx;\ + y2 = table[4 * s + 1] * (1 - wx) + table[4 * t + 1] * wx;\ + z2 = table[4 * s + 2] * (1 - wx) + table[4 * t + 2] * wx;\ + a2 = table[4 * s + 3] * (1 - wx) + table[4 * t + 3] * wx;\ + x = x * (1 - wy) + x2 * wy;\ + y = y * (1 - wy) + y2 * wy;\ + z = z * (1 - wy) + z2 * wy;\ + a = a * (1 - wy) + a2 * wy;\ + s -= nx, t -= nx;\ + }\ + if ((size_t)iz != nz - 1) {\ + s += nxy, t += nxy;\ + x1 = table[4 * s + 0] * (1 - wx) + table[4 * t + 0] * wx;\ + y1 = table[4 * s + 1] * (1 - wx) + table[4 * t + 1] * wx;\ + z1 = table[4 * s + 2] * (1 - wx) + table[4 * t + 2] * wx;\ + a1 = table[4 * s + 3] * (1 - wx) + table[4 * t + 3] * wx;\ + if ((size_t)iy != ny - 1) {\ + s += nx, t += nx;\ + x2 = table[4 * s + 0] * (1 - wx) + table[4 * t + 0] * wx;\ + y2 = table[4 * s + 1] * (1 - wx) + table[4 * t + 1] * wx;\ + z2 = table[4 * s + 2] * (1 - wx) + table[4 * t + 2] * wx;\ + a2 = table[4 * s + 3] * (1 - wx) + table[4 * t + 3] * wx;\ + x1 = x1 * (1 - wy) + x2 * wy;\ + y1 = y1 * (1 - wy) + y2 * wy;\ + z1 = z1 * (1 - wy) + z2 * wy;\ + a1 = a1 * (1 - wy) + a2 * wy;\ + }\ + x = x * (1 - wz) + x1 * wz;\ + y = y * (1 - wz) + y1 * wz;\ + z = z * (1 - wz) + z1 * wz;\ + a = a * (1 - wz) + a1 * wz;\ + }\ + }\ + ((TYPE *)(stream->buf))[4 * i + 0] = x;\ + ((TYPE *)(stream->buf))[4 * i + 1] = y;\ + ((TYPE *)(stream->buf))[4 * i + 2] = z;\ + ((TYPE *)(stream->buf))[4 * i + 3] *= a;\ + }\ + n *= stream->pixel_size;\ + m -= n;\ + ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");\ + memmove(stream->buf, stream->buf + n, stream->ptr -= n);\ + } while (eread_stream(stream, SIZE_MAX));\ + if (stream->ptr)\ + eprintf("%s: incomplete frame\n", stream->file);\ + done:\ + free(table);\ + } + +PROCESS(double, lf) +PROCESS(float, f) + + +int +main(int argc, char *argv[]) +{ + struct stream stream, spectrum; + void (*process)(struct stream *stream, struct stream *spectrum); + + ARGBEGIN { + case 'y': + luma = 1; + break; + case 'z': + nz = etozu_flag('z', UARGF(), 1, SIZE_MAX); + break; + default: + usage(); + } ARGEND; + + if (argc != 1) + usage(); + + eopen_stream(&stream, NULL); + eopen_stream(&spectrum, argv[0]); + + if (!strcmp(stream.pixfmt, "xyza")) + process = process_lf; + else if (!strcmp(stream.pixfmt, "xyza f")) + process = process_f; + else + eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt); + + if (strcmp(stream.pixfmt, spectrum.pixfmt)) + eprintf("videos use incompatible pixel formats\n"); + + echeck_dimensions(&spectrum, WIDTH | HEIGHT, "spectrum"); + + fprint_stream_head(stdout, &stream); + efflush(stdout, "<stdout>"); + process(&stream, &spectrum); + return 0; +}