Add gradients - blind - suckless command-line video editing utility | |
git clone git://git.suckless.org/blind | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit e76229ac4f95ac8c6e4e38e60689a09a091e4048 | |
parent c91c5cb8e892f1c19c970cef033cc03c9f47f98a | |
Author: Mattias Andrée <[email protected]> | |
Date: Sun, 2 Jul 2017 23:58:01 +0200 | |
Add gradients | |
Signed-off-by: Mattias Andrée <[email protected]> | |
Diffstat: | |
M Makefile | 12 ++++++++++++ | |
A src/blind-cone-gradient.c | 126 +++++++++++++++++++++++++++++… | |
A src/blind-coordinate-field.c | 77 +++++++++++++++++++++++++++++… | |
A src/blind-double-sinus-wave.c | 94 +++++++++++++++++++++++++++++… | |
A src/blind-linear-gradient.c | 101 +++++++++++++++++++++++++++++… | |
A src/blind-radial-gradient.c | 128 +++++++++++++++++++++++++++++… | |
A src/blind-round-wave.c | 89 +++++++++++++++++++++++++++++… | |
A src/blind-sawtooth-wave.c | 84 +++++++++++++++++++++++++++++… | |
A src/blind-sinc-wave.c | 114 +++++++++++++++++++++++++++++… | |
A src/blind-sinus-wave.c | 94 +++++++++++++++++++++++++++++… | |
A src/blind-spiral-gradient.c | 134 +++++++++++++++++++++++++++++… | |
A src/blind-square-gradient.c | 109 +++++++++++++++++++++++++++++… | |
A src/blind-triangular-wave.c | 101 +++++++++++++++++++++++++++++… | |
M src/video-math.h | 4 ++++ | |
14 files changed, 1267 insertions(+), 0 deletions(-) | |
--- | |
diff --git a/Makefile b/Makefile | |
@@ -9,7 +9,9 @@ BIN =\ | |
blind-colour-srgb\ | |
blind-compress\ | |
blind-concat\ | |
+ blind-cone-gradient\ | |
blind-convert\ | |
+ blind-coordinate-field\ | |
blind-crop\ | |
blind-cross-product\ | |
blind-cut\ | |
@@ -17,6 +19,7 @@ BIN =\ | |
blind-disperse\ | |
blind-dissolve\ | |
blind-dot-product\ | |
+ blind-double-sinus-wave\ | |
blind-extend\ | |
blind-find-rectangle\ | |
blind-flip\ | |
@@ -29,26 +32,35 @@ BIN =\ | |
blind-gauss-blur\ | |
blind-interleave\ | |
blind-invert-luma\ | |
+ blind-linear-gradient\ | |
blind-make-kernel\ | |
blind-next-frame\ | |
blind-norm\ | |
blind-quaternion-product\ | |
blind-premultiply\ | |
+ blind-radial-gradient\ | |
blind-read-head\ | |
blind-repeat\ | |
blind-reverse\ | |
blind-rewrite-head\ | |
+ blind-round-wave\ | |
+ blind-sawtooth-wave\ | |
blind-set-alpha\ | |
blind-set-luma\ | |
blind-set-saturation\ | |
blind-single-colour\ | |
+ blind-sinc-wave\ | |
+ blind-sinus-wave\ | |
blind-skip-pattern\ | |
+ blind-spiral-gradient\ | |
blind-split\ | |
blind-split-cols\ | |
blind-split-rows\ | |
+ blind-square-gradient\ | |
blind-stack\ | |
blind-tee\ | |
blind-time-blur\ | |
+ blind-triangular-wave\ | |
blind-to-image\ | |
blind-to-named\ | |
blind-to-portable\ | |
diff --git a/src/blind-cone-gradient.c b/src/blind-cone-gradient.c | |
@@ -0,0 +1,126 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+#include "common.h" | |
+ | |
+USAGE("[-a | -s] -w width -h height") | |
+ | |
+static int anticlockwise = 0; | |
+static int symmetric = 0; | |
+static size_t width = 0; | |
+static size_t height = 0; | |
+static int with_multiplier = 0; | |
+ | |
+ | |
+#define PROCESS(TYPE, SUFFIX)\ | |
+ static void\ | |
+ process_##SUFFIX(struct stream *stream)\ | |
+ {\ | |
+ typedef TYPE pixel_t[4];\ | |
+ pixel_t buf[BUFSIZ / sizeof(pixel_t)];\ | |
+ TYPE *params, x1, y1, x2, y2;\ | |
+ TYPE x, y, u, v, m = 1;\ | |
+ size_t ix, iy, ptr = 0;\ | |
+ for (;;) {\ | |
+ while (stream->ptr < stream->frame_size) {\ | |
+ if (!eread_stream(stream, stream->frame_size -… | |
+ ewriteall(STDOUT_FILENO, buf, ptr * si… | |
+ return;\ | |
+ }\ | |
+ }\ | |
+ params = (TYPE *)stream->buf;\ | |
+ x1 = (params)[0];\ | |
+ y1 = (params)[1];\ | |
+ x2 = (params)[4];\ | |
+ y2 = (params)[5];\ | |
+ if (with_multiplier)\ | |
+ m = (params)[9];\ | |
+ memmove(stream->buf, stream->buf + stream->frame_size,\ | |
+ stream->ptr -= stream->frame_size);\ | |
+ \ | |
+ x2 -= x1;\ | |
+ y2 -= y1;\ | |
+ u = atan2(y2, x2);\ | |
+ \ | |
+ for (iy = 0; iy < height; iy++) {\ | |
+ y = (TYPE)iy - y1;\ | |
+ for (ix = 0; ix < width; ix++) {\ | |
+ x = (TYPE)ix - x1;\ | |
+ v = atan2(y, x);\ | |
+ v -= u;\ | |
+ v += 2 * (TYPE)M_PI;\ | |
+ v = mod(v, 2 * (TYPE)M_PI);\ | |
+ v /= 2 * (TYPE)M_PI;\ | |
+ if (anticlockwise)\ | |
+ v = 1 - v;\ | |
+ v *= m;\ | |
+ if (symmetric) {\ | |
+ v = mod(2 * v, (TYPE)2);\ | |
+ if (v > 1)\ | |
+ v = 2 - v;\ | |
+ }\ | |
+ buf[ptr][0] = buf[ptr][1] = buf[ptr][2… | |
+ if (++ptr == ELEMENTSOF(buf)) {\ | |
+ ewriteall(STDOUT_FILENO, buf, … | |
+ ptr = 0;\ | |
+ }\ | |
+ }\ | |
+ }\ | |
+ }\ | |
+ } | |
+ | |
+PROCESS(double, lf) | |
+PROCESS(float, f) | |
+ | |
+ | |
+int | |
+main(int argc, char *argv[]) | |
+{ | |
+ struct stream stream; | |
+ void (*process)(struct stream *stream); | |
+ | |
+ ARGBEGIN { | |
+ case 'a': | |
+ if (symmetric) | |
+ usage(); | |
+ anticlockwise = 1; | |
+ break; | |
+ case 's': | |
+ if (anticlockwise) | |
+ usage(); | |
+ symmetric = 1; | |
+ break; | |
+ case 'w': | |
+ width = etozu_flag('w', UARGF(), 1, SIZE_MAX); | |
+ break; | |
+ case 'h': | |
+ height = etozu_flag('h', UARGF(), 1, SIZE_MAX); | |
+ break; | |
+ default: | |
+ usage(); | |
+ } ARGEND; | |
+ | |
+ if (!width || !height || argc) | |
+ usage(); | |
+ | |
+ eopen_stream(&stream, NULL); | |
+ | |
+ 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… | |
+ | |
+ if (stream.width > 3 || stream.height > 3 || | |
+ stream.width * stream.height < 2 || | |
+ stream.width * stream.height > 3) | |
+ eprintf("<stdin>: each frame must contain exactly 2 or 3 pixel… | |
+ | |
+ with_multiplier = stream.width * stream.height == 3; | |
+ | |
+ stream.width = width; | |
+ stream.height = height; | |
+ fprint_stream_head(stdout, &stream); | |
+ efflush(stdout, "<stdout>"); | |
+ process(&stream); | |
+ return 0; | |
+} | |
diff --git a/src/blind-coordinate-field.c b/src/blind-coordinate-field.c | |
@@ -0,0 +1,77 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+#include "common.h" | |
+ | |
+USAGE("[-f frames | -f 'inf'] [-F pixel-format] -w width -h height") | |
+ | |
+static struct stream stream = { .width = 0, .height = 0, .frames = 1 }; | |
+static int inf = 0; | |
+ | |
+#define PROCESS(TYPE)\ | |
+ do {\ | |
+ TYPE buf[4] = {0, 0, 0, 0};\ | |
+ size_t x, y;\ | |
+ \ | |
+ while (inf || stream.frames--) {\ | |
+ for (y = 0; y < stream.height; y++) {\ | |
+ buf[1] = (TYPE)y;\ | |
+ for (x = 0; x < stream.width; x++) {\ | |
+ buf[0] = (TYPE)x;\ | |
+ if (write(STDOUT_FILENO, buf, sizeof(b… | |
+ eprintf("write <stdout>:");\ | |
+ }\ | |
+ }\ | |
+ }\ | |
+ } while (0) | |
+ | |
+static void process_lf(void) {PROCESS(double);} | |
+static void process_f(void) {PROCESS(float);} | |
+ | |
+int | |
+main(int argc, char *argv[]) | |
+{ | |
+ char *arg; | |
+ const char *pixfmt = "xyza"; | |
+ void (*process)(void); | |
+ | |
+ ARGBEGIN { | |
+ case 'f': | |
+ arg = UARGF(); | |
+ if (!strcmp(arg, "inf")) | |
+ inf = 1, stream.frames = 0; | |
+ else | |
+ stream.frames = etozu_flag('f', arg, 1, SIZE_MAX); | |
+ break; | |
+ case 'F': | |
+ pixfmt = UARGF(); | |
+ break; | |
+ case 'w': | |
+ stream.width = etozu_flag('w', UARGF(), 1, SIZE_MAX); | |
+ break; | |
+ case 'h': | |
+ stream.height = etozu_flag('h', UARGF(), 1, SIZE_MAX); | |
+ break; | |
+ default: | |
+ usage(); | |
+ } ARGEND; | |
+ | |
+ if (!stream.width || !stream.height || argc) | |
+ usage(); | |
+ | |
+ if (inf) | |
+ einf_check_fd(STDOUT_FILENO, "<stdout>"); | |
+ | |
+ pixfmt = get_pixel_format(pixfmt, "xyza"); | |
+ if (!strcmp(pixfmt, "xyza")) | |
+ process = process_lf; | |
+ else if (!strcmp(pixfmt, "xyza f")) | |
+ process = process_f; | |
+ else | |
+ eprintf("pixel format %s is not supported, try xyza\n", pixfmt… | |
+ | |
+ strcpy(stream.pixfmt, pixfmt); | |
+ fprint_stream_head(stdout, &stream); | |
+ efflush(stdout, "<stdout>"); | |
+ | |
+ process(); | |
+ return 0; | |
+} | |
diff --git a/src/blind-double-sinus-wave.c b/src/blind-double-sinus-wave.c | |
@@ -0,0 +1,94 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+#include "common.h" | |
+ | |
+USAGE("[-e]") | |
+ | |
+static int equal = 0; | |
+ | |
+ | |
+#define PROCESS(TYPE, SUFFIX)\ | |
+ static void\ | |
+ process_##SUFFIX(struct stream *stream)\ | |
+ {\ | |
+ size_t i, n;\ | |
+ TYPE x, y, z, a;\ | |
+ do {\ | |
+ n = stream->ptr / stream->pixel_size;\ | |
+ if (equal) {\ | |
+ for (i = 0; i < n; i++) {\ | |
+ a = ((TYPE *)(stream->buf))[4 * i + 3]… | |
+ a = posmod(a, (TYPE)2);\ | |
+ a = a > 1 ? 2 - a : a;\ | |
+ a = 1 - (sin(a * (2 * (TYPE)M_PI)) + 1… | |
+ ((TYPE *)(stream->buf))[4 * i + 0] = a… | |
+ ((TYPE *)(stream->buf))[4 * i + 1] = a… | |
+ ((TYPE *)(stream->buf))[4 * i + 2] = a… | |
+ ((TYPE *)(stream->buf))[4 * i + 3] = a… | |
+ }\ | |
+ } else {\ | |
+ for (i = 0; i < n; i++) {\ | |
+ x = ((TYPE *)(stream->buf))[4 * i + 0]… | |
+ y = ((TYPE *)(stream->buf))[4 * i + 1]… | |
+ z = ((TYPE *)(stream->buf))[4 * i + 2]… | |
+ a = ((TYPE *)(stream->buf))[4 * i + 3]… | |
+ x = posmod(x, (TYPE)1);\ | |
+ y = posmod(y, (TYPE)1);\ | |
+ z = posmod(z, (TYPE)1);\ | |
+ a = posmod(a, (TYPE)1);\ | |
+ x = x > 1 ? 2 - x : x;\ | |
+ y = y > 1 ? 2 - y : y;\ | |
+ z = z > 1 ? 2 - z : z;\ | |
+ a = a > 1 ? 2 - a : a;\ | |
+ x = 1 - (sin(x * (2 * (TYPE)M_PI)) + 1… | |
+ y = 1 - (sin(y * (2 * (TYPE)M_PI)) + 1… | |
+ z = 1 - (sin(z * (2 * (TYPE)M_PI)) + 1… | |
+ a = 1 - (sin(a * (2 * (TYPE)M_PI)) + 1… | |
+ ((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;\ | |
+ 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);\ | |
+ } | |
+ | |
+PROCESS(double, lf) | |
+PROCESS(float, f) | |
+ | |
+ | |
+int | |
+main(int argc, char *argv[]) | |
+{ | |
+ struct stream stream; | |
+ void (*process)(struct stream *stream); | |
+ | |
+ ARGBEGIN { | |
+ case 'e': | |
+ equal = 1; | |
+ break; | |
+ default: | |
+ usage(); | |
+ } ARGEND; | |
+ | |
+ if (argc) | |
+ usage(); | |
+ | |
+ eopen_stream(&stream, NULL); | |
+ | |
+ 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… | |
+ | |
+ fprint_stream_head(stdout, &stream); | |
+ efflush(stdout, "<stdout>"); | |
+ process(&stream); | |
+ return 0; | |
+} | |
diff --git a/src/blind-linear-gradient.c b/src/blind-linear-gradient.c | |
@@ -0,0 +1,101 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+#include "common.h" | |
+ | |
+USAGE("[-b] -w width -h height") | |
+ | |
+static int bilinear = 0; | |
+static size_t width = 0; | |
+static size_t height = 0; | |
+ | |
+ | |
+#define PROCESS(TYPE, SUFFIX)\ | |
+ static void\ | |
+ process_##SUFFIX(struct stream *stream)\ | |
+ {\ | |
+ typedef TYPE pixel_t[4];\ | |
+ pixel_t buf[BUFSIZ / sizeof(pixel_t)];\ | |
+ TYPE *params, x1, y1, x2, y2, norm2;\ | |
+ TYPE x, y;\ | |
+ size_t ix, iy, ptr = 0;\ | |
+ for (;;) {\ | |
+ while (stream->ptr < stream->frame_size) {\ | |
+ if (!eread_stream(stream, stream->frame_size -… | |
+ ewriteall(STDOUT_FILENO, buf, ptr * si… | |
+ return;\ | |
+ }\ | |
+ }\ | |
+ params = (TYPE *)stream->buf;\ | |
+ x1 = (params)[0];\ | |
+ y1 = (params)[1];\ | |
+ x2 = (params)[4];\ | |
+ y2 = (params)[5];\ | |
+ memmove(stream->buf, stream->buf + stream->frame_size,\ | |
+ stream->ptr -= stream->frame_size);\ | |
+ \ | |
+ x2 -= x1;\ | |
+ y2 -= y1;\ | |
+ norm2 = x2 * x2 + y2 * y2;\ | |
+ \ | |
+ for (iy = 0; iy < height; iy++) {\ | |
+ y = (TYPE)iy - y1;\ | |
+ for (ix = 0; ix < width; ix++) {\ | |
+ x = (TYPE)ix - x1;\ | |
+ x = (x * x2 + y * y2) / norm2;\ | |
+ if (bilinear)\ | |
+ x = abs(x);\ | |
+ buf[ptr][0] = buf[ptr][1] = buf[ptr][2… | |
+ if (++ptr == ELEMENTSOF(buf)) {\ | |
+ ewriteall(STDOUT_FILENO, buf, … | |
+ ptr = 0;\ | |
+ }\ | |
+ }\ | |
+ }\ | |
+ }\ | |
+ } | |
+ | |
+PROCESS(double, lf) | |
+PROCESS(float, f) | |
+ | |
+ | |
+int | |
+main(int argc, char *argv[]) | |
+{ | |
+ struct stream stream; | |
+ void (*process)(struct stream *stream); | |
+ | |
+ ARGBEGIN { | |
+ case 'b': | |
+ bilinear = 1; | |
+ break; | |
+ case 'w': | |
+ width = etozu_flag('w', UARGF(), 1, SIZE_MAX); | |
+ break; | |
+ case 'h': | |
+ height = etozu_flag('h', UARGF(), 1, SIZE_MAX); | |
+ break; | |
+ default: | |
+ usage(); | |
+ } ARGEND; | |
+ | |
+ if (!width || !height || argc) | |
+ usage(); | |
+ | |
+ eopen_stream(&stream, NULL); | |
+ | |
+ 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… | |
+ | |
+ if (stream.width > 2 || stream.height > 2 || stream.width * stream.hei… | |
+ eprintf("<stdin>: each frame must contain exactly 2 pixels\n"); | |
+ | |
+ stream.width = width; | |
+ stream.height = height; | |
+ fprint_stream_head(stdout, &stream); | |
+ efflush(stdout, "<stdout>"); | |
+ process(&stream); | |
+ return 0; | |
+} | |
diff --git a/src/blind-radial-gradient.c b/src/blind-radial-gradient.c | |
@@ -0,0 +1,128 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+#include "common.h" | |
+ | |
+USAGE("-w width -h height") | |
+ | |
+static size_t width = 0; | |
+static size_t height = 0; | |
+static int with_params; | |
+ | |
+ | |
+#define PROCESS(TYPE, SUFFIX)\ | |
+ static void\ | |
+ process_##SUFFIX(struct stream *stream)\ | |
+ {\ | |
+ typedef TYPE pixel_t[4];\ | |
+ pixel_t buf[BUFSIZ / sizeof(pixel_t)];\ | |
+ TYPE *params, x1, y1, x2, y2, norm, rd = 1, pe = 2, re = 2, e … | |
+ TYPE x, y, p, r, rx, ry;\ | |
+ size_t ix, iy, ptr = 0;\ | |
+ for (;;) {\ | |
+ while (stream->ptr < stream->frame_size) {\ | |
+ if (!eread_stream(stream, stream->frame_size -… | |
+ ewriteall(STDOUT_FILENO, buf, ptr * si… | |
+ return;\ | |
+ }\ | |
+ }\ | |
+ params = (TYPE *)stream->buf;\ | |
+ x1 = (params)[0];\ | |
+ y1 = (params)[1];\ | |
+ x2 = (params)[4];\ | |
+ y2 = (params)[5];\ | |
+ if (with_params) {\ | |
+ pe = (params)[8];\ | |
+ re = (params)[9];\ | |
+ rd = (params)[10];\ | |
+ e = 1 / sqrt(pe * re);\ | |
+ }\ | |
+ memmove(stream->buf, stream->buf + stream->frame_size,\ | |
+ stream->ptr -= stream->frame_size);\ | |
+ \ | |
+ x2 -= x1;\ | |
+ y2 -= y1;\ | |
+ norm = sqrt(x2 * x2 + y2 * y2);\ | |
+ \ | |
+ if (!with_params) {\ | |
+ for (iy = 0; iy < height; iy++) {\ | |
+ y = (TYPE)iy - y1;\ | |
+ y *= y;\ | |
+ for (ix = 0; ix < width; ix++) {\ | |
+ x = (TYPE)ix - x1;\ | |
+ x = sqrt(x * x + y) / norm;\ | |
+ buf[ptr][0] = buf[ptr][1] = bu… | |
+ if (++ptr == ELEMENTSOF(buf)) … | |
+ ewriteall(STDOUT_FILEN… | |
+ ptr = 0;\ | |
+ }\ | |
+ }\ | |
+ }\ | |
+ } else {\ | |
+ for (iy = 0; iy < height; iy++) {\ | |
+ y = (TYPE)iy - y1;\ | |
+ for (ix = 0; ix < width; ix++) {\ | |
+ x = (TYPE)ix - x1;\ | |
+ p = (x * x2 + y * y2) / norm;\ | |
+ rx = x - p * x2 / norm;\ | |
+ ry = y - p * y2 / norm;\ | |
+ r = sqrt(rx * rx + ry * ry) / … | |
+ p = pow(abs(p / norm), pe);\ | |
+ r = pow(abs(r / norm), re);\ | |
+ x = pow(p + r, e);\ | |
+ buf[ptr][0] = buf[ptr][1] = bu… | |
+ if (++ptr == ELEMENTSOF(buf)) … | |
+ ewriteall(STDOUT_FILEN… | |
+ ptr = 0;\ | |
+ }\ | |
+ }\ | |
+ }\ | |
+ }\ | |
+ }\ | |
+ } | |
+ | |
+PROCESS(double, lf) | |
+PROCESS(float, f) | |
+ | |
+ | |
+int | |
+main(int argc, char *argv[]) | |
+{ | |
+ struct stream stream; | |
+ void (*process)(struct stream *stream); | |
+ | |
+ ARGBEGIN { | |
+ case 'w': | |
+ width = etozu_flag('w', UARGF(), 1, SIZE_MAX); | |
+ break; | |
+ case 'h': | |
+ height = etozu_flag('h', UARGF(), 1, SIZE_MAX); | |
+ break; | |
+ default: | |
+ usage(); | |
+ } ARGEND; | |
+ | |
+ if (!width || !height || argc) | |
+ usage(); | |
+ | |
+ eopen_stream(&stream, NULL); | |
+ | |
+ 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… | |
+ | |
+ if (stream.width > 3 || stream.height > 3 || | |
+ stream.width * stream.height < 2 || | |
+ stream.width * stream.height > 3) | |
+ eprintf("<stdin>: each frame must contain exactly 2 pixels\n"); | |
+ | |
+ with_params = stream.width * stream.height == 3; | |
+ | |
+ stream.width = width; | |
+ stream.height = height; | |
+ fprint_stream_head(stdout, &stream); | |
+ efflush(stdout, "<stdout>"); | |
+ process(&stream); | |
+ return 0; | |
+} | |
diff --git a/src/blind-round-wave.c b/src/blind-round-wave.c | |
@@ -0,0 +1,89 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+#include "common.h" | |
+ | |
+USAGE("[-e]") | |
+ | |
+static int equal = 0; | |
+ | |
+ | |
+#define PROCESS(TYPE, SUFFIX)\ | |
+ static void\ | |
+ process_##SUFFIX(struct stream *stream)\ | |
+ {\ | |
+ size_t i, n;\ | |
+ TYPE x, y, z, a;\ | |
+ do {\ | |
+ n = stream->ptr / stream->pixel_size;\ | |
+ if (equal) {\ | |
+ for (i = 0; i < n; i++) {\ | |
+ a = ((TYPE *)(stream->buf))[4 * i + 3]… | |
+ a = mod(a + 1, (TYPE)4) - 1;\ | |
+ a = a < 1 ? 1 - a * a / 2 : (a - 2) * … | |
+ ((TYPE *)(stream->buf))[4 * i + 0] = a… | |
+ ((TYPE *)(stream->buf))[4 * i + 1] = a… | |
+ ((TYPE *)(stream->buf))[4 * i + 2] = a… | |
+ ((TYPE *)(stream->buf))[4 * i + 3] = a… | |
+ }\ | |
+ } else {\ | |
+ for (i = 0; i < n; i++) {\ | |
+ x = ((TYPE *)(stream->buf))[4 * i + 0]… | |
+ y = ((TYPE *)(stream->buf))[4 * i + 1]… | |
+ z = ((TYPE *)(stream->buf))[4 * i + 2]… | |
+ a = ((TYPE *)(stream->buf))[4 * i + 3]… | |
+ x = mod(x + 1, (TYPE)4) - 1;\ | |
+ y = mod(y + 1, (TYPE)4) - 1;\ | |
+ z = mod(z + 1, (TYPE)4) - 1;\ | |
+ a = mod(a + 1, (TYPE)4) - 1;\ | |
+ x = x < 1 ? 1 - x * x / 2 : (x - 2) * … | |
+ y = y < 1 ? 1 - y * y / 2 : (y - 2) * … | |
+ z = z < 1 ? 1 - z * z / 2 : (z - 2) * … | |
+ a = a < 1 ? 1 - a * a / 2 : (a - 2) * … | |
+ ((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;\ | |
+ 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);\ | |
+ } | |
+ | |
+PROCESS(double, lf) | |
+PROCESS(float, f) | |
+ | |
+ | |
+int | |
+main(int argc, char *argv[]) | |
+{ | |
+ struct stream stream; | |
+ void (*process)(struct stream *stream); | |
+ | |
+ ARGBEGIN { | |
+ case 'e': | |
+ equal = 1; | |
+ break; | |
+ default: | |
+ usage(); | |
+ } ARGEND; | |
+ | |
+ if (argc) | |
+ usage(); | |
+ | |
+ eopen_stream(&stream, NULL); | |
+ | |
+ 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… | |
+ | |
+ fprint_stream_head(stdout, &stream); | |
+ efflush(stdout, "<stdout>"); | |
+ process(&stream); | |
+ return 0; | |
+} | |
diff --git a/src/blind-sawtooth-wave.c b/src/blind-sawtooth-wave.c | |
@@ -0,0 +1,84 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+#include "common.h" | |
+ | |
+USAGE("[-e]") | |
+ | |
+static int equal = 0; | |
+ | |
+ | |
+#define PROCESS(TYPE, SUFFIX)\ | |
+ static void\ | |
+ process_##SUFFIX(struct stream *stream)\ | |
+ {\ | |
+ size_t i, n;\ | |
+ TYPE x, y, z, a;\ | |
+ do {\ | |
+ n = stream->ptr / stream->pixel_size;\ | |
+ if (equal) {\ | |
+ for (i = 0; i < n; i++) {\ | |
+ a = ((TYPE *)(stream->buf))[4 * i + 3]… | |
+ a = posmod(a, (TYPE)1);\ | |
+ ((TYPE *)(stream->buf))[4 * i + 0] = a… | |
+ ((TYPE *)(stream->buf))[4 * i + 1] = a… | |
+ ((TYPE *)(stream->buf))[4 * i + 2] = a… | |
+ ((TYPE *)(stream->buf))[4 * i + 3] = a… | |
+ }\ | |
+ } else {\ | |
+ for (i = 0; i < n; i++) {\ | |
+ x = ((TYPE *)(stream->buf))[4 * i + 0]… | |
+ y = ((TYPE *)(stream->buf))[4 * i + 1]… | |
+ z = ((TYPE *)(stream->buf))[4 * i + 2]… | |
+ a = ((TYPE *)(stream->buf))[4 * i + 3]… | |
+ x = posmod(x, (TYPE)1);\ | |
+ y = posmod(y, (TYPE)1);\ | |
+ z = posmod(z, (TYPE)1);\ | |
+ a = posmod(a, (TYPE)1);\ | |
+ ((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;\ | |
+ 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);\ | |
+ } | |
+ | |
+PROCESS(double, lf) | |
+PROCESS(float, f) | |
+ | |
+ | |
+int | |
+main(int argc, char *argv[]) | |
+{ | |
+ struct stream stream; | |
+ void (*process)(struct stream *stream); | |
+ | |
+ ARGBEGIN { | |
+ case 'e': | |
+ equal = 1; | |
+ break; | |
+ default: | |
+ usage(); | |
+ } ARGEND; | |
+ | |
+ if (argc) | |
+ usage(); | |
+ | |
+ eopen_stream(&stream, NULL); | |
+ | |
+ 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… | |
+ | |
+ fprint_stream_head(stdout, &stream); | |
+ efflush(stdout, "<stdout>"); | |
+ process(&stream); | |
+ return 0; | |
+} | |
diff --git a/src/blind-sinc-wave.c b/src/blind-sinc-wave.c | |
@@ -0,0 +1,114 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+#include "common.h" | |
+ | |
+USAGE("[-e] [theta0-stream]") | |
+ | |
+static int equal = 0; | |
+ | |
+ | |
+#define PROCESS(TYPE, SUFFIX)\ | |
+ static void\ | |
+ process_##SUFFIX(struct stream *grad, struct stream *theta0)\ | |
+ {\ | |
+ size_t i, n, m = 0;\ | |
+ TYPE *theta0xyza;\ | |
+ TYPE x, theta0x = 0;\ | |
+ TYPE y, theta0y = 0;\ | |
+ TYPE z, theta0z = 0;\ | |
+ TYPE a, theta0a = 0;\ | |
+ echeck_dimensions(grad, WIDTH | HEIGHT, NULL);\ | |
+ do {\ | |
+ if (!m) {\ | |
+ m = grad->frame_size;\ | |
+ if (theta0) {\ | |
+ while (theta0->ptr < theta0->frame_siz… | |
+ if (!eread_stream(theta0, thet… | |
+ return;\ | |
+ theta0xyza = (TYPE *)theta0->buf;\ | |
+ theta0x = (theta0xyza)[0];\ | |
+ theta0y = (theta0xyza)[1];\ | |
+ theta0z = (theta0xyza)[2];\ | |
+ theta0a = (theta0xyza)[3];\ | |
+ memmove(theta0->buf, theta0->buf + the… | |
+ theta0->ptr -= theta0->frame_s… | |
+ }\ | |
+ }\ | |
+ n = MIN(grad->ptr, m) / grad->pixel_size;\ | |
+ if (equal) {\ | |
+ for (i = 0; i < n; i++) {\ | |
+ a = ((TYPE *)(grad->buf))[4 * i + 3];\ | |
+ a = (a ? sin(a + theta0y) / a : sin(a … | |
+ ((TYPE *)(grad->buf))[4 * i + 0] = a;\ | |
+ ((TYPE *)(grad->buf))[4 * i + 1] = a;\ | |
+ ((TYPE *)(grad->buf))[4 * i + 2] = a;\ | |
+ ((TYPE *)(grad->buf))[4 * i + 3] = a;\ | |
+ }\ | |
+ } else {\ | |
+ for (i = 0; i < n; i++) {\ | |
+ x = ((TYPE *)(grad->buf))[4 * i + 0];\ | |
+ y = ((TYPE *)(grad->buf))[4 * i + 1];\ | |
+ z = ((TYPE *)(grad->buf))[4 * i + 2];\ | |
+ a = ((TYPE *)(grad->buf))[4 * i + 3];\ | |
+ x = (x ? sin(x + theta0x) / x : sin(x … | |
+ y = (y ? sin(y + theta0y) / y : sin(y … | |
+ z = (z ? sin(z + theta0z) / z : sin(z … | |
+ a = (a ? sin(a + theta0a) / a : sin(a … | |
+ ((TYPE *)(grad->buf))[4 * i + 0] = x;\ | |
+ ((TYPE *)(grad->buf))[4 * i + 1] = y;\ | |
+ ((TYPE *)(grad->buf))[4 * i + 2] = z;\ | |
+ ((TYPE *)(grad->buf))[4 * i + 3] = a;\ | |
+ }\ | |
+ }\ | |
+ n *= grad->pixel_size;\ | |
+ m -= n;\ | |
+ ewriteall(STDOUT_FILENO, grad->buf, n, "<stdout>");\ | |
+ memmove(grad->buf, grad->buf + n, grad->ptr -= n);\ | |
+ } while (eread_stream(grad, SIZE_MAX));\ | |
+ if (grad->ptr)\ | |
+ eprintf("%s: incomplete frame\n", grad->file);\ | |
+ } | |
+ | |
+PROCESS(double, lf) | |
+PROCESS(float, f) | |
+ | |
+ | |
+int | |
+main(int argc, char *argv[]) | |
+{ | |
+ struct stream stream, theta0; | |
+ int have_theta0; | |
+ void (*process)(struct stream *grad, struct stream *theta0); | |
+ | |
+ ARGBEGIN { | |
+ case 'e': | |
+ equal = 1; | |
+ break; | |
+ default: | |
+ usage(); | |
+ } ARGEND; | |
+ | |
+ if (argc > 1) | |
+ usage(); | |
+ | |
+ eopen_stream(&stream, NULL); | |
+ if ((have_theta0 = argc == 1)) { | |
+ eopen_stream(&theta0, argv[0]); | |
+ if (theta0.width != 1 || theta0.height != 1) | |
+ eprintf("theta0-stream must be of dimension 1x1\n"); | |
+ } | |
+ | |
+ 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… | |
+ | |
+ if (have_theta0 && strcmp(stream.pixfmt, theta0.pixfmt)) | |
+ eprintf("videos use incompatible pixel formats\n"); | |
+ | |
+ fprint_stream_head(stdout, &stream); | |
+ efflush(stdout, "<stdout>"); | |
+ process(&stream, have_theta0 ? &theta0 : NULL); | |
+ return 0; | |
+} | |
diff --git a/src/blind-sinus-wave.c b/src/blind-sinus-wave.c | |
@@ -0,0 +1,94 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+#include "common.h" | |
+ | |
+USAGE("[-e]") | |
+ | |
+static int equal = 0; | |
+ | |
+ | |
+#define PROCESS(TYPE, SUFFIX)\ | |
+ static void\ | |
+ process_##SUFFIX(struct stream *stream)\ | |
+ {\ | |
+ size_t i, n;\ | |
+ TYPE x, y, z, a;\ | |
+ do {\ | |
+ n = stream->ptr / stream->pixel_size;\ | |
+ if (equal) {\ | |
+ for (i = 0; i < n; i++) {\ | |
+ a = ((TYPE *)(stream->buf))[4 * i + 3]… | |
+ a = posmod(a, (TYPE)2);\ | |
+ a = a > 1 ? 2 - a : a;\ | |
+ a = 1 - (cos(a * (TYPE)M_PI) + 1) / 2;\ | |
+ ((TYPE *)(stream->buf))[4 * i + 0] = a… | |
+ ((TYPE *)(stream->buf))[4 * i + 1] = a… | |
+ ((TYPE *)(stream->buf))[4 * i + 2] = a… | |
+ ((TYPE *)(stream->buf))[4 * i + 3] = a… | |
+ }\ | |
+ } else {\ | |
+ for (i = 0; i < n; i++) {\ | |
+ x = ((TYPE *)(stream->buf))[4 * i + 0]… | |
+ y = ((TYPE *)(stream->buf))[4 * i + 1]… | |
+ z = ((TYPE *)(stream->buf))[4 * i + 2]… | |
+ a = ((TYPE *)(stream->buf))[4 * i + 3]… | |
+ x = posmod(x, (TYPE)1);\ | |
+ y = posmod(y, (TYPE)1);\ | |
+ z = posmod(z, (TYPE)1);\ | |
+ a = posmod(a, (TYPE)1);\ | |
+ x = x > 1 ? 2 - x : x;\ | |
+ y = y > 1 ? 2 - y : y;\ | |
+ z = z > 1 ? 2 - z : z;\ | |
+ a = a > 1 ? 2 - a : a;\ | |
+ x = 1 - (cos(x * (TYPE)M_PI) + 1) / 2;\ | |
+ y = 1 - (cos(y * (TYPE)M_PI) + 1) / 2;\ | |
+ z = 1 - (cos(z * (TYPE)M_PI) + 1) / 2;\ | |
+ a = 1 - (cos(a * (TYPE)M_PI) + 1) / 2;\ | |
+ ((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;\ | |
+ 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);\ | |
+ } | |
+ | |
+PROCESS(double, lf) | |
+PROCESS(float, f) | |
+ | |
+ | |
+int | |
+main(int argc, char *argv[]) | |
+{ | |
+ struct stream stream; | |
+ void (*process)(struct stream *stream); | |
+ | |
+ ARGBEGIN { | |
+ case 'e': | |
+ equal = 1; | |
+ break; | |
+ default: | |
+ usage(); | |
+ } ARGEND; | |
+ | |
+ if (argc) | |
+ usage(); | |
+ | |
+ eopen_stream(&stream, NULL); | |
+ | |
+ 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… | |
+ | |
+ fprint_stream_head(stdout, &stream); | |
+ efflush(stdout, "<stdout>"); | |
+ process(&stream); | |
+ return 0; | |
+} | |
diff --git a/src/blind-spiral-gradient.c b/src/blind-spiral-gradient.c | |
@@ -0,0 +1,134 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+#include "common.h" | |
+ | |
+USAGE("[-al] -w width -h height") | |
+ | |
+static int anticlockwise = 0; | |
+static int logarithmic = 0; | |
+static size_t width = 0; | |
+static size_t height = 0; | |
+static int with_params; | |
+ | |
+ | |
+#define PROCESS(TYPE, SUFFIX)\ | |
+ static void\ | |
+ process_##SUFFIX(struct stream *stream)\ | |
+ {\ | |
+ typedef TYPE pixel_t[4];\ | |
+ pixel_t buf[BUFSIZ / sizeof(pixel_t)];\ | |
+ TYPE *params, x1, y1, x2, y2, b, r, u, v;\ | |
+ TYPE x, y, a = 0, e = 1, p = 1, k = 1, ep = 1;\ | |
+ size_t ix, iy, ptr = 0;\ | |
+ for (;;) {\ | |
+ while (stream->ptr < stream->frame_size) {\ | |
+ if (!eread_stream(stream, stream->frame_size -… | |
+ ewriteall(STDOUT_FILENO, buf, ptr * si… | |
+ return;\ | |
+ }\ | |
+ }\ | |
+ params = (TYPE *)stream->buf;\ | |
+ x1 = (params)[0];\ | |
+ y1 = (params)[1];\ | |
+ x2 = (params)[4];\ | |
+ y2 = (params)[5];\ | |
+ if (with_params) {\ | |
+ a = (params)[8];\ | |
+ e = (params)[9];\ | |
+ p = (params)[10];\ | |
+ k = (params)[11];\ | |
+ ep = 1 / (e * p);\ | |
+ }\ | |
+ memmove(stream->buf, stream->buf + stream->frame_size,\ | |
+ stream->ptr -= stream->frame_size);\ | |
+ \ | |
+ x2 -= x1;\ | |
+ y2 -= y1;\ | |
+ u = atan2(y2, x2);\ | |
+ b = sqrt(x2 * x2 + y2 * y2);\ | |
+ if (logarithmic)\ | |
+ b = log(b);\ | |
+ b /= pow(2 * (TYPE)M_PI, e);\ | |
+ \ | |
+ for (iy = 0; iy < height; iy++) {\ | |
+ y = (TYPE)iy - y1;\ | |
+ for (ix = 0; ix < width; ix++) {\ | |
+ x = (TYPE)ix - x1;\ | |
+ v = atan2(y, x);\ | |
+ if (anticlockwise)\ | |
+ v = 1 - v;\ | |
+ v -= u;\ | |
+ v += 4 * (TYPE)M_PI;\ | |
+ v = mod(v, 2 * (TYPE)M_PI);\ | |
+ r = sqrt(x * x + y * y);\ | |
+ r -= a;\ | |
+ if (!logarithmic) {\ | |
+ r = pow(r / b, ep);\ | |
+ r = (r - v) / (2 * (TYPE)M_PI)… | |
+ } else if (r) {\ | |
+ r = log(r / k);\ | |
+ r = pow(r / b, ep);\ | |
+ r = (r - v) / (2 * (TYPE)M_PI)… | |
+ }\ | |
+ buf[ptr][0] = buf[ptr][1] = buf[ptr][2… | |
+ if (++ptr == ELEMENTSOF(buf)) {\ | |
+ ewriteall(STDOUT_FILENO, buf, … | |
+ ptr = 0;\ | |
+ }\ | |
+ }\ | |
+ }\ | |
+ }\ | |
+ } | |
+ | |
+PROCESS(double, lf) | |
+PROCESS(float, f) | |
+ | |
+ | |
+int | |
+main(int argc, char *argv[]) | |
+{ | |
+ struct stream stream; | |
+ void (*process)(struct stream *stream); | |
+ | |
+ ARGBEGIN { | |
+ case 'a': | |
+ anticlockwise = 1; | |
+ break; | |
+ case 'l': | |
+ logarithmic = 1; | |
+ break; | |
+ case 'w': | |
+ width = etozu_flag('w', UARGF(), 1, SIZE_MAX); | |
+ break; | |
+ case 'h': | |
+ height = etozu_flag('h', UARGF(), 1, SIZE_MAX); | |
+ break; | |
+ default: | |
+ usage(); | |
+ } ARGEND; | |
+ | |
+ if (!width || !height || argc) | |
+ usage(); | |
+ | |
+ eopen_stream(&stream, NULL); | |
+ | |
+ 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… | |
+ | |
+ if (stream.width > 3 || stream.height > 3 || | |
+ stream.width * stream.height < 2 || | |
+ stream.width * stream.height > 3) | |
+ eprintf("<stdin>: each frame must contain exactly 2 or 3 pixel… | |
+ | |
+ with_params = stream.width * stream.height == 3; | |
+ | |
+ stream.width = width; | |
+ stream.height = height; | |
+ fprint_stream_head(stdout, &stream); | |
+ efflush(stdout, "<stdout>"); | |
+ process(&stream); | |
+ return 0; | |
+} | |
diff --git a/src/blind-square-gradient.c b/src/blind-square-gradient.c | |
@@ -0,0 +1,109 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+#include "common.h" | |
+ | |
+USAGE("-w width -h height") | |
+ | |
+static size_t width = 0; | |
+static size_t height = 0; | |
+static int with_multiplier; | |
+ | |
+ | |
+#define PROCESS(TYPE, SUFFIX)\ | |
+ static void\ | |
+ process_##SUFFIX(struct stream *stream)\ | |
+ {\ | |
+ typedef TYPE pixel_t[4];\ | |
+ pixel_t buf[BUFSIZ / sizeof(pixel_t)];\ | |
+ TYPE *params, x1, y1, x2, y2, norm, rd = 1; \ | |
+ TYPE x, y, p, r, rx, ry;\ | |
+ size_t ix, iy, ptr = 0;\ | |
+ for (;;) {\ | |
+ while (stream->ptr < stream->frame_size) {\ | |
+ if (!eread_stream(stream, stream->frame_size -… | |
+ ewriteall(STDOUT_FILENO, buf, ptr * si… | |
+ return;\ | |
+ }\ | |
+ }\ | |
+ params = (TYPE *)stream->buf;\ | |
+ x1 = (params)[0];\ | |
+ y1 = (params)[1];\ | |
+ x2 = (params)[4];\ | |
+ y2 = (params)[5];\ | |
+ if (with_multiplier)\ | |
+ rd = (params)[9];\ | |
+ memmove(stream->buf, stream->buf + stream->frame_size,\ | |
+ stream->ptr -= stream->frame_size);\ | |
+ \ | |
+ x2 -= x1;\ | |
+ y2 -= y1;\ | |
+ norm = sqrt(x2 * x2 + y2 * y2);\ | |
+ x2 /= norm;\ | |
+ y2 /= norm;\ | |
+ \ | |
+ for (iy = 0; iy < height; iy++) {\ | |
+ y = (TYPE)iy - y1;\ | |
+ for (ix = 0; ix < width; ix++) {\ | |
+ x = (TYPE)ix - x1;\ | |
+ p = x * x2 + y * y2;\ | |
+ rx = x - p * x2;\ | |
+ ry = y - p * y2;\ | |
+ r = sqrt(rx * rx + ry * ry) / rd;\ | |
+ p = abs(p);\ | |
+ x = MAX(p, r) / norm;\ | |
+ buf[ptr][0] = buf[ptr][1] = buf[ptr][2… | |
+ if (++ptr == ELEMENTSOF(buf)) {\ | |
+ ewriteall(STDOUT_FILENO, buf, … | |
+ ptr = 0;\ | |
+ }\ | |
+ }\ | |
+ }\ | |
+ }\ | |
+ } | |
+ | |
+PROCESS(double, lf) | |
+PROCESS(float, f) | |
+ | |
+ | |
+int | |
+main(int argc, char *argv[]) | |
+{ | |
+ struct stream stream; | |
+ void (*process)(struct stream *stream); | |
+ | |
+ ARGBEGIN { | |
+ case 'w': | |
+ width = etozu_flag('w', UARGF(), 1, SIZE_MAX); | |
+ break; | |
+ case 'h': | |
+ height = etozu_flag('h', UARGF(), 1, SIZE_MAX); | |
+ break; | |
+ default: | |
+ usage(); | |
+ } ARGEND; | |
+ | |
+ if (!width || !height || argc) | |
+ usage(); | |
+ | |
+ eopen_stream(&stream, NULL); | |
+ | |
+ 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… | |
+ | |
+ if (stream.width > 3 || stream.height > 3 || | |
+ stream.width * stream.height < 2 || | |
+ stream.width * stream.height > 3) | |
+ eprintf("<stdin>: each frame must contain exactly 2 or 3 pixel… | |
+ | |
+ with_multiplier = stream.width * stream.height == 3; | |
+ | |
+ stream.width = width; | |
+ stream.height = height; | |
+ fprint_stream_head(stdout, &stream); | |
+ efflush(stdout, "<stdout>"); | |
+ process(&stream); | |
+ return 0; | |
+} | |
diff --git a/src/blind-triangular-wave.c b/src/blind-triangular-wave.c | |
@@ -0,0 +1,101 @@ | |
+/* See LICENSE file for copyright and license details. */ | |
+#include "common.h" | |
+ | |
+USAGE("[-es]") | |
+ | |
+static int equal = 0; | |
+static int spiral = 0; | |
+ | |
+ | |
+#define PROCESS(TYPE, SUFFIX)\ | |
+ static void\ | |
+ process_##SUFFIX(struct stream *stream)\ | |
+ {\ | |
+ size_t i, n;\ | |
+ TYPE x, y, z, a;\ | |
+ do {\ | |
+ n = stream->ptr / stream->pixel_size;\ | |
+ if (equal) {\ | |
+ for (i = 0; i < n; i++) {\ | |
+ a = ((TYPE *)(stream->buf))[4 * i + 3]… | |
+ a = posmod(a, (TYPE)2);\ | |
+ a = a > 1 ? 2 - a : a;\ | |
+ if (spiral)\ | |
+ a = (a > 0.5 ? 1 - a : a) * 2;\ | |
+ ((TYPE *)(stream->buf))[4 * i + 0] = a… | |
+ ((TYPE *)(stream->buf))[4 * i + 1] = a… | |
+ ((TYPE *)(stream->buf))[4 * i + 2] = a… | |
+ ((TYPE *)(stream->buf))[4 * i + 3] = a… | |
+ }\ | |
+ } else {\ | |
+ for (i = 0; i < n; i++) {\ | |
+ x = ((TYPE *)(stream->buf))[4 * i + 0]… | |
+ y = ((TYPE *)(stream->buf))[4 * i + 1]… | |
+ z = ((TYPE *)(stream->buf))[4 * i + 2]… | |
+ a = ((TYPE *)(stream->buf))[4 * i + 3]… | |
+ x = posmod(x, (TYPE)2);\ | |
+ y = posmod(y, (TYPE)2);\ | |
+ z = posmod(z, (TYPE)2);\ | |
+ a = posmod(a, (TYPE)2);\ | |
+ x = x > 1 ? 2 - x : x;\ | |
+ y = y > 1 ? 2 - y : y;\ | |
+ z = z > 1 ? 2 - z : z;\ | |
+ a = a > 1 ? 2 - a : a;\ | |
+ if (spiral) {\ | |
+ x = (x > 0.5 ? 1 - x : x) * 2;\ | |
+ y = (y > 0.5 ? 1 - y : y) * 2;\ | |
+ z = (z > 0.5 ? 1 - z : z) * 2;\ | |
+ a = (a > 0.5 ? 1 - a : a) * 2;\ | |
+ }\ | |
+ ((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;\ | |
+ 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);\ | |
+ } | |
+ | |
+PROCESS(double, lf) | |
+PROCESS(float, f) | |
+ | |
+ | |
+int | |
+main(int argc, char *argv[]) | |
+{ | |
+ struct stream stream; | |
+ void (*process)(struct stream *stream); | |
+ | |
+ ARGBEGIN { | |
+ case 'e': | |
+ equal = 1; | |
+ break; | |
+ case 's': | |
+ spiral = 1; | |
+ break; | |
+ default: | |
+ usage(); | |
+ } ARGEND; | |
+ | |
+ if (argc) | |
+ usage(); | |
+ | |
+ eopen_stream(&stream, NULL); | |
+ | |
+ 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… | |
+ | |
+ fprint_stream_head(stdout, &stream); | |
+ efflush(stdout, "<stdout>"); | |
+ process(&stream); | |
+ return 0; | |
+} | |
diff --git a/src/video-math.h b/src/video-math.h | |
@@ -59,6 +59,7 @@ posmodf(float a, float b) | |
#define pow(...) MATH_GENERIC_N(pow, __VA_ARGS__) | |
#define log2(...) MATH_GENERIC_1(log2, __VA_ARGS__) | |
+#define log(...) MATH_GENERIC_1(log, __VA_ARGS__) | |
#define abs(...) MATH_GENERIC_1(fabs, __VA_ARGS__) | |
#define sqrt(...) MATH_GENERIC_1(sqrt, __VA_ARGS__) | |
#define exp(...) MATH_GENERIC_1(exp, __VA_ARGS__) | |
@@ -68,6 +69,9 @@ posmodf(float a, float b) | |
#define nnpow(...) MATH_GENERIC_N(nnpow, __VA_ARGS__) | |
#define mod(...) MATH_GENERIC_N(fmod, __VA_ARGS__) | |
#define posmod(...) MATH_GENERIC_N(posmod, __VA_ARGS__) | |
+#define cos(...) MATH_GENERIC_1(cos, __VA_ARGS__) | |
+#define sin(...) MATH_GENERIC_1(sin, __VA_ARGS__) | |
+#define atan2(...) MATH_GENERIC_N(atan2, __VA_ARGS__) | |
#define srgb_encode(...) BLIND_GENERIC_1(srgb_encode, __VA_ARGS__) | |
#define srgb_decode(...) BLIND_GENERIC_1(srgb_decode, __VA_ARGS__) |