diff options
| author | Mattias Andrée <maandree@kth.se> | 2017-01-09 03:51:26 +0100 |
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2017-01-09 03:51:26 +0100 |
| commit | 76cdf509b36bb0012cde9bc1760cdf3b26874af2 (patch) | |
| tree | cc984bb82eaf9911d6173343a9e90bb20e9ddffb /src/vu-stack.c | |
| parent | Readme: add format (diff) | |
| download | blind-76cdf509b36bb0012cde9bc1760cdf3b26874af2.tar.gz blind-76cdf509b36bb0012cde9bc1760cdf3b26874af2.tar.bz2 blind-76cdf509b36bb0012cde9bc1760cdf3b26874af2.tar.xz | |
Use CIE XYZ instead of sRGB
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to 'src/vu-stack.c')
| -rw-r--r-- | src/vu-stack.c | 186 |
1 files changed, 85 insertions, 101 deletions
diff --git a/src/vu-stack.c b/src/vu-stack.c index af765e2..508c000 100644 --- a/src/vu-stack.c +++ b/src/vu-stack.c @@ -1,113 +1,90 @@ /* See LICENSE file for copyright and license details. */ #include "arg.h" +#include "stream.h" #include "util.h" #include <fcntl.h> #include <inttypes.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> #include <string.h> #include <unistd.h> -struct file -{ - int fd; - unsigned char buf[1024]; - size_t ptr; - const char *file; -}; - -static unsigned int -clip(unsigned int value) -{ - return value < 0 ? 0 : value > 255 ? 255 : value; -} - static void -blend(struct file *files, size_t n_files, size_t n) +process_xyza(struct stream *streams, size_t n_streams, size_t n) { - double r1, g1, b1, a1; - double r2, g2, b2, a2; + double x1, y1, z1, a1; + double x2, y2, z2, a2; size_t i, j; - for (i = 0; i < n; i += 4) { - r1 = srgb_decode(files->buf[i + 0] / 255.); - g1 = srgb_decode(files->buf[i + 1] / 255.); - b1 = srgb_decode(files->buf[i + 2] / 255.); - a1 = files->buf[i + 3] / 255.; - for (j = 1; j < n_files;) { - r2 = srgb_decode(files[j].buf[i + 0] / 255.); - g2 = srgb_decode(files[j].buf[i + 1] / 255.); - b2 = srgb_decode(files[j].buf[i + 2] / 255.); - a2 = files[j].buf[i + 3] / 255.; - a2 /= ++j; - r1 = r1 * a1 * (1 - a2) + r2 * a2; - g1 = g1 * a1 * (1 - a2) + g2 * a2; - b1 = b1 * a1 * (1 - a2) + b2 * a2; + for (i = 0; i < n; i += streams->pixel_size) { + x1 = ((double *)(streams[0].buf + i))[0]; + y1 = ((double *)(streams[0].buf + i))[1]; + z1 = ((double *)(streams[0].buf + i))[2]; + a1 = ((double *)(streams[0].buf + i))[3]; + for (j = 1; j < n_streams; j++) { + x2 = ((double *)(streams[j].buf + i))[0]; + y2 = ((double *)(streams[j].buf + i))[1]; + z2 = ((double *)(streams[j].buf + i))[2]; + a2 = ((double *)(streams[j].buf + i))[3]; + x1 = x1 * a1 * (1 - a2) + x2 * a2; + y1 = y1 * a1 * (1 - a2) + y2 * a2; + z1 = z1 * a1 * (1 - a2) + z2 * a2; a1 = a1 * (1 - a2) + a2; } - r1 = srgb_encode(r1) * 255 + 0.5; - g1 = srgb_encode(g1) * 255 + 0.5; - b1 = srgb_encode(b1) * 255 + 0.5; - a1 = a1 * 255 * 0.5; - files->buf[i + 0] = clip((unsigned int)r1); - files->buf[i + 1] = clip((unsigned int)g1); - files->buf[i + 2] = clip((unsigned int)b1); - files->buf[i + 3] = clip((unsigned int)a1); + ((double *)(streams[0].buf + i))[0] = x1; + ((double *)(streams[0].buf + i))[1] = y1; + ((double *)(streams[0].buf + i))[2] = z1; + ((double *)(streams[0].buf + i))[3] = a1; } } static void -stack(struct file *files, size_t n_files, size_t n) +process_xyza_b(struct stream *streams, size_t n_streams, size_t n) { - double r1, g1, b1, a1; - double r2, g2, b2, a2; + double x1, y1, z1, a1; + double x2, y2, z2, a2; size_t i, j; - for (i = 0; i < n; i += 4) { - r1 = srgb_decode(files->buf[i + 0] / 255.); - g1 = srgb_decode(files->buf[i + 1] / 255.); - b1 = srgb_decode(files->buf[i + 2] / 255.); - a1 = files->buf[i + 3] / 255.; - for (j = 1; j < n_files; j++) { - r2 = srgb_decode(files[j].buf[i + 0] / 255.); - g2 = srgb_decode(files[j].buf[i + 1] / 255.); - b2 = srgb_decode(files[j].buf[i + 2] / 255.); - a2 = files[j].buf[i + 3] / 255.; - r1 = r1 * a1 * (1 - a2) + r2 * a2; - g1 = g1 * a1 * (1 - a2) + g2 * a2; - b1 = b1 * a1 * (1 - a2) + b2 * a2; + for (i = 0; i < n; i += streams->pixel_size) { + x1 = ((double *)(streams[0].buf + i))[0]; + y1 = ((double *)(streams[0].buf + i))[1]; + z1 = ((double *)(streams[0].buf + i))[2]; + a1 = ((double *)(streams[0].buf + i))[3]; + for (j = 1; j < n_streams;) { + x2 = ((double *)(streams[j].buf + i))[0]; + y2 = ((double *)(streams[j].buf + i))[1]; + z2 = ((double *)(streams[j].buf + i))[2]; + a2 = ((double *)(streams[j].buf + i))[3]; + a2 /= ++j; + x1 = x1 * a1 * (1 - a2) + x2 * a2; + y1 = y1 * a1 * (1 - a2) + y2 * a2; + z1 = z1 * a1 * (1 - a2) + z2 * a2; a1 = a1 * (1 - a2) + a2; } - r1 = srgb_encode(r1) * 255 + 0.5; - g1 = srgb_encode(g1) * 255 + 0.5; - b1 = srgb_encode(b1) * 255 + 0.5; - a1 = a1 * 255 * 0.5; - files->buf[i + 0] = clip((unsigned int)r1); - files->buf[i + 1] = clip((unsigned int)g1); - files->buf[i + 2] = clip((unsigned int)b1); - files->buf[i + 3] = clip((unsigned int)a1); + ((double *)(streams[0].buf + i))[0] = x1; + ((double *)(streams[0].buf + i))[1] = y1; + ((double *)(streams[0].buf + i))[2] = z1; + ((double *)(streams[0].buf + i))[3] = a1; } } static void usage(void) { - eprintf("usage: %s [-b] bottom-image ... top-image\n", argv0); + eprintf("usage: %s [-b] bottom-stream ... top-stream\n", argv0); } int main(int argc, char *argv[]) { - struct file *files; - size_t n_files; - int blend_flag = 0; + struct stream *streams; + size_t n_streams; + int blend = 0; size_t i, j, n; ssize_t r; size_t closed; + void (*process)(struct stream *streams, size_t n_streams, size_t n); ARGBEGIN { case 'b': - blend_flag = 1; + blend = 1; break; default: usage(); @@ -116,56 +93,63 @@ main(int argc, char *argv[]) if (argc < 2) usage(); - n_files = (size_t)argc; - files = calloc(n_files, sizeof(*files)); - if (!files) + n_streams = (size_t)argc; + streams = calloc(n_streams, sizeof(*streams)); + if (!streams) eprintf("calloc:"); - for (i = 0; i < n_files; i++) { - files[i].fd = open(argv[i], O_RDONLY); - if (files[i].fd < 0) - eprintf("open %s:", argv[i]); - files[i].file = argv[i]; + for (i = 0; i < n_streams; i++) { + streams[i].file = argv[i]; + streams[i].fd = open(streams[i].file, O_RDONLY); + if (streams[i].fd < 0) + eprintf("open %s:", streams[i].file); + if (i) { + if (streams[i].width != streams->width || streams[i].height != streams->height) + eprintf("videos do not have the same geometry\n"); + if (strcmp(streams[i].pixfmt, streams->pixfmt)) + eprintf("videos use incompatible pixel formats\n"); + } } - while (n_files) { + if (!strcmp(streams->pixfmt, "xyza")) + process = blend ? process_xyza_b : process_xyza; + else + eprintf("pixel format %s is not supported, try xyza\n", streams->pixfmt); + + while (n_streams) { n = SIZE_MAX; - for (i = 0; i < n_files; i++) { - r = read(files[i].fd, files[i].buf + files[i].ptr, sizeof(files[i].buf) - files[i].ptr); - if (r < 0) { - eprintf("read %s:", files[i].file); - } else if (r == 0) { - close(files[i].fd); - files[i].fd = -1; - } else { - files[i].ptr += (size_t)r; + for (i = 0; i < n_streams; i++) { + if (streams[i].ptr < sizeof(streams->buf) && !eread_stream(streams + i, SIZE_MAX)) { + close(streams[i].fd); + streams[i].fd = -1; } - if (files[i].ptr && files[i].ptr < n) - n = files[i].ptr; + if (streams[i].ptr && streams[i].ptr < n) + n = streams[i].ptr; } - n -= n & 3; + n -= n % streams->pixel_size; - (blend_flag ? blend : stack)(files, n_files, n); + process(streams, n_streams, n); for (j = 0; j < n;) { - r = write(STDOUT_FILENO, files->buf + j, n - j); + r = write(STDOUT_FILENO, streams->buf + j, n - j); if (r < 0) eprintf("write <stdout>:"); j += (size_t)r; } closed = SIZE_MAX; - for (i = 0; i < n_files; i++) { - memmove(files[i].buf, files[i].buf + n, files[i].ptr -= n); - if (files[i].ptr < 4 && files[i].fd < 0 && closed == SIZE_MAX) + for (i = 0; i < n_streams; i++) { + memmove(streams[i].buf, streams[i].buf + n, streams[i].ptr -= n); + if (streams[i].ptr < streams->pixel_size && streams[i].fd < 0 && closed == SIZE_MAX) closed = i; } if (closed != SIZE_MAX) { - for (i = (j = closed) + 1; i < n_files; i++) - if (files[i].ptr < 4 && files[i].fd < 0) - files[j++] = files[i]; - n_files = j; + for (i = (j = closed) + 1; i < n_streams; i++) + if (streams[i].ptr < streams->pixel_size && streams[i].fd < 0) + streams[j++] = streams[i]; + n_streams = j; } } + free(streams); return 0; } |
