blind

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

commit 7bce90acb004f897f0b1684ec582de4eaf8a17a4
parent db851082efbc51f657fe8343cdb8ea5bd974ce44
Author: Mattias Andrée <maandree@kth.se>
Date:   Tue, 10 Jan 2017 01:43:17 +0100

Add vu-set-saturation

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

Diffstat:
MMakefile | 1+
Asrc/vu-set-saturation.c | 150+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 151 insertions(+), 0 deletions(-)

diff --git a/Makefile b/Makefile @@ -17,6 +17,7 @@ BIN =\ vu-reverse\ vu-set-alpha\ vu-set-luma\ + vu-set-saturation\ vu-single-colour\ vu-stack\ vu-write-head diff --git a/src/vu-set-saturation.c b/src/vu-set-saturation.c @@ -0,0 +1,150 @@ +/* See LICENSE file for copyright and license details. */ +#include "arg.h" +#include "stream.h" +#include "util.h" + +#include <fcntl.h> +#include <stdint.h> +#include <string.h> +#include <unistd.h> + +static void +usage(void) +{ + eprintf("usage: %s [-w] saturation-stream\n", argv0); +} + +static void +process_xyza(struct stream *colour, struct stream *satur, size_t n) +{ + size_t i; + double s, *x, *z, X, Z; + X = D65_XYY_X / D65_XYY_Y; + Z = 1 / D65_XYY_Y - 1 - X; + for (i = 0; i < n; i += colour->pixel_size) { + s = ((double *)(satur->buf + i))[1]; + s *= ((double *)(satur->buf + i))[3]; + x = ((double *)(colour->buf + i)) + 0; + z = ((double *)(colour->buf + i)) + 2; + *x = (*x - X) * s + X; + *z = (*z - Z) * s + Z; + } +} + +static void +process_xyza_w(struct stream *colour, struct stream *satur, size_t n) +{ + size_t i; + double s, *x, *z, X, Z; + for (i = 0; i < n; i += colour->pixel_size) { + X = ((double *)(satur->buf + i))[0]; + Z = ((double *)(satur->buf + i))[2]; + s = ((double *)(satur->buf + i))[1]; + s *= ((double *)(satur->buf + i))[3]; + x = ((double *)(colour->buf + i)) + 0; + z = ((double *)(colour->buf + i)) + 2; + *x = (*x - X) * s + X; + *z = (*z - Z) * s + Z; + } +} + +int +main(int argc, char *argv[]) +{ + struct stream colour; + struct stream satur; + int whitepoint = 0; + ssize_t r; + size_t i, n; + void (*process)(struct stream *colour, struct stream *satur, size_t n) = NULL; + + ARGBEGIN { + case 'w': + whitepoint = 1; + break; + default: + usage(); + } ARGEND; + + if (argc != 1) + usage(); + + colour.file = "<stdin>"; + colour.fd = STDIN_FILENO; + einit_stream(&colour); + + satur.file = argv[0]; + satur.fd = open(satur.file, O_RDONLY); + if (satur.fd < 0) + eprintf("open %s:", satur.file); + einit_stream(&satur); + + if (colour.width != satur.width || colour.height != satur.height) + eprintf("videos do not have the same geometry\n"); + if (colour.pixel_size != satur.pixel_size) + eprintf("videos use incompatible pixel formats\n"); + + if (!strcmp(colour.pixfmt, "xyza")) + process = whitepoint ? process_xyza_w : process_xyza; + else + eprintf("pixel format %s is not supported, try xyza\n", colour.pixfmt); + + for (;;) { + if (colour.ptr < sizeof(colour.buf) && !eread_stream(&colour, SIZE_MAX)) { + close(colour.fd); + colour.fd = -1; + break; + } + if (satur.ptr < sizeof(satur.buf) && !eread_stream(&satur, SIZE_MAX)) { + close(satur.fd); + satur.fd = -1; + break; + } + + n = colour.ptr < satur.ptr ? colour.ptr : satur.ptr; + n -= n % colour.pixel_size; + colour.ptr -= n; + satur.ptr -= n; + + process(&colour, &satur, n); + + for (i = 0; i < n; i += (size_t)r) { + r = write(STDOUT_FILENO, colour.buf + i, n - i); + if (r < 0) + eprintf("write <stdout>:"); + } + + if ((n & 3) || colour.ptr != satur.ptr) { + memmove(colour.buf, colour.buf + n, colour.ptr); + memmove(satur.buf, satur.buf + n, satur.ptr); + } + } + + if (satur.fd >= 0) + close(satur.fd); + + for (i = 0; i < colour.ptr; i += (size_t)r) { + r = write(STDOUT_FILENO, colour.buf + i, colour.ptr - i); + if (r < 0) + eprintf("write <stdout>:"); + } + + if (colour.fd >= 0) { + for (;;) { + colour.ptr = 0; + if (!eread_stream(&colour, SIZE_MAX)) { + close(colour.fd); + colour.fd = -1; + break; + } + + for (i = 0; i < colour.ptr; i += (size_t)r) { + r = write(STDOUT_FILENO, colour.buf + i, colour.ptr - i); + if (r < 0) + eprintf("write <stdout>:"); + } + } + } + + return 0; +}