blind

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

commit c216ac3049102422a41ba2c9476b0dbf4f3e4034
parent e0763df25edbc1ec72ab77d0c22fde41f06e9222
Author: Mattias Andrée <maandree@kth.se>
Date:   Sun, 16 Jul 2017 00:59:42 +0200

Use #include instead of #define

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

Diffstat:
Makefile | 1+
src/blind-apply-palette.c | 102+++++++++++++++++++++++++++++++++++++++++--------------------------------------
src/blind-chroma-key.c | 116+++++++++++++++++++++++++++++++++++++++++--------------------------------------
src/blind-cone-gradient.c | 137++++++++++++++++++++++++++++++++++++++++---------------------------------------
src/blind-coordinate-field.c | 43++++++++++++++++++++++++-------------------
src/blind-cross-product.c | 52++++++++++++++++++++++++++++------------------------
src/blind-dot-product.c | 42+++++++++++++++++++++++-------------------
src/blind-double-sine-wave.c | 78+++++++++++++++++++++++++++++++++++++++++-------------------------------------
src/blind-dual-key.c | 90++++++++++++++++++++++++++++++++++++++++++-------------------------------------
src/blind-extract-alpha.c | 60++++++++++++++++++++++++++++++++----------------------------
src/blind-invert-matrix.c | 118+++++++++++++++++++++++++++++++++++++++++--------------------------------------
src/blind-linear-gradient.c | 99+++++++++++++++++++++++++++++++++++++++++--------------------------------------
src/blind-matrix-orthoproject.c | 98++++++++++++++++++++++++++++++++++++++++++-------------------------------------
src/blind-matrix-reflect.c | 94++++++++++++++++++++++++++++++++++++++++++-------------------------------------
src/blind-matrix-rotate.c | 98++++++++++++++++++++++++++++++++++++++++++-------------------------------------
src/blind-matrix-scale.c | 72+++++++++++++++++++++++++++++++++++++++---------------------------------
src/blind-matrix-shear.c | 88++++++++++++++++++++++++++++++++++++++++++-------------------------------------
src/blind-matrix-translate.c | 72+++++++++++++++++++++++++++++++++++++++---------------------------------
src/blind-matrix-transpose.c | 70++++++++++++++++++++++++++++++++++++++--------------------------------
src/blind-multiply-matrices.c | 106++++++++++++++++++++++++++++++++++++++++++-------------------------------------
src/blind-norm.c | 70+++++++++++++++++++++++++++++++++++++---------------------------------
src/blind-premultiply.c | 58+++++++++++++++++++++++++++++++---------------------------
src/blind-quaternion-product.c | 52++++++++++++++++++++++++++++------------------------
src/blind-radial-gradient.c | 150+++++++++++++++++++++++++++++++++++++++++--------------------------------------
src/blind-round-wave.c | 74+++++++++++++++++++++++++++++++++++++++-----------------------------------
src/blind-sawtooth-wave.c | 70+++++++++++++++++++++++++++++++++++++---------------------------------
src/blind-set-luma.c | 166+++++++++++++++++++++++++++++++++++++++++--------------------------------------
src/blind-sinc-wave.c | 130+++++++++++++++++++++++++++++++++++++++++--------------------------------------
src/blind-sine-wave.c | 78+++++++++++++++++++++++++++++++++++++++++-------------------------------------
src/blind-single-colour.c | 55++++++++++++++++++++++++++++++-------------------------
src/blind-spectrum.c | 234++++++++++++++++++++++++++++++++++++++++---------------------------------------
src/blind-spiral-gradient.c | 208++++++++++++++++++++++++++++++++++++++++---------------------------------------
src/blind-square-gradient.c | 112+++++++++++++++++++++++++++++++++++++++++--------------------------------------
src/blind-tee.c | 4----
src/blind-time-blur.c | 81++++++++++++++++++++++++++++++++++++++-----------------------------------------
src/blind-to-text.c | 2--
src/blind-to-video.c | 108++++++++++++++++++++++++++++++++++++++++++-------------------------------------
src/blind-triangular-wave.c | 84+++++++++++++++++++++++++++++++++++++++++--------------------------------------
src/blind-unpremultiply.c | 62+++++++++++++++++++++++++++++++++-----------------------------
src/blind-vector-projection.c | 74+++++++++++++++++++++++++++++++++++++++-----------------------------------
src/common.h | 4++++
src/define-functions.h | 13+++++++++++++
42 files changed, 1850 insertions(+), 1675 deletions(-)

diff --git a/Makefile b/Makefile @@ -112,6 +112,7 @@ COMMON_OBJ =\ HDR =\ arg.h\ common.h\ + define-functions.h\ stream.h\ util.h\ util/to.h\ diff --git a/src/blind-apply-palette.c b/src/blind-apply-palette.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("palette-stream") @@ -16,55 +17,8 @@ distance_xyz(double x1, double y1, double z1, double a1, double x2, double y2, d return sqrt(x2 + y2 + z2 + a2); } -#define PROCESS(TYPE, SUFFIX)\ - static void\ - process_##SUFFIX(struct stream *stream, struct stream *palette, char *pal)\ - {\ - size_t i, j, n, m;\ - size_t palsiz = palette->width * palette->height;\ - size_t best = 0;\ - TYPE x, y, z, a, lx = 0, ly = 0, lz = 0, la = 0;\ - TYPE cx, cy, cz, ca;\ - double distance, best_distance = 0;\ - while (eread_frame(palette, pal)) {\ - m = stream->frame_size;\ - do {\ - n = MIN(stream->ptr, m) / stream->pixel_size;\ - for (i = 0; i < n; i++) {\ - x = ((TYPE *)(stream->buf + i * stream->pixel_size))[0];\ - y = ((TYPE *)(stream->buf + i * stream->pixel_size))[1];\ - z = ((TYPE *)(stream->buf + i * stream->pixel_size))[2];\ - a = ((TYPE *)(stream->buf + i * stream->pixel_size))[3];\ - if ((!i && m == stream->frame_size) || x != lx || y != ly || z != lz || a != la) {\ - for (j = 0; j < palsiz; j++) {\ - cx = ((TYPE *)(pal + j * stream->pixel_size))[0];\ - cy = ((TYPE *)(pal + j * stream->pixel_size))[1];\ - cz = ((TYPE *)(pal + j * stream->pixel_size))[2];\ - ca = ((TYPE *)(pal + j * stream->pixel_size))[3];\ - distance = compare((double)x, (double)y, (double)z, (double)a,\ - (double)cx, (double)cy, (double)cz, (double)ca);\ - if (!j || distance < best_distance) {\ - best_distance = distance;\ - best = j;\ - }\ - }\ - lx = x, ly = y, lz = z, la = a;\ - }\ - memcpy(stream->buf + i * stream->pixel_size,\ - pal + best * stream->pixel_size,\ - stream->pixel_size);\ - }\ - m -= n *= stream->pixel_size;\ - ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>");\ - memmove(stream->buf, stream->buf + n, stream->ptr -= n);\ - } while (m && eread_stream(stream, SIZE_MAX));\ - if (m)\ - eprintf("%s: incomplete frame\n", stream->file);\ - }\ - } - -PROCESS(double, lf) -PROCESS(float, f) +#define FILE "blind-apply-palette.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -101,3 +55,53 @@ main(int argc, char *argv[]) free(pal); return 0; } + +#else + +static void +PROCESS(struct stream *stream, struct stream *palette, char *pal) +{ + size_t i, j, n, m; + size_t palsiz = palette->width * palette->height; + size_t best = 0; + TYPE x, y, z, a, lx = 0, ly = 0, lz = 0, la = 0; + TYPE cx, cy, cz, ca; + double distance, best_distance = 0; + while (eread_frame(palette, pal)) { + m = stream->frame_size; + do { + n = MIN(stream->ptr, m) / stream->pixel_size; + for (i = 0; i < n; i++) { + x = ((TYPE *)(stream->buf + i * stream->pixel_size))[0]; + y = ((TYPE *)(stream->buf + i * stream->pixel_size))[1]; + z = ((TYPE *)(stream->buf + i * stream->pixel_size))[2]; + a = ((TYPE *)(stream->buf + i * stream->pixel_size))[3]; + if ((!i && m == stream->frame_size) || x != lx || y != ly || z != lz || a != la) { + for (j = 0; j < palsiz; j++) { + cx = ((TYPE *)(pal + j * stream->pixel_size))[0]; + cy = ((TYPE *)(pal + j * stream->pixel_size))[1]; + cz = ((TYPE *)(pal + j * stream->pixel_size))[2]; + ca = ((TYPE *)(pal + j * stream->pixel_size))[3]; + distance = compare((double)x, (double)y, (double)z, (double)a, + (double)cx, (double)cy, (double)cz, (double)ca); + if (!j || distance < best_distance) { + best_distance = distance; + best = j; + } + } + lx = x, ly = y, lz = z, la = a; + } + memcpy(stream->buf + i * stream->pixel_size, + pal + best * stream->pixel_size, + stream->pixel_size); + } + m -= n *= stream->pixel_size; + ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>"); + memmove(stream->buf, stream->buf + n, stream->ptr -= n); + } while (m && eread_stream(stream, SIZE_MAX)); + if (m) + eprintf("%s: incomplete frame\n", stream->file); + } +} + +#endif diff --git a/src/blind-chroma-key.c b/src/blind-chroma-key.c @@ -1,64 +1,11 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("key-stream") -#define PROCESS(TYPE, SUFFIX)\ - static void\ - process_##SUFFIX(struct stream *stream, struct stream *key)\ - {\ - size_t i, n, m = 0;\ - TYPE x1, y1, z1, a1, a2, variance2, *keyxyza;\ - TYPE x, y, z, d;\ - do {\ - if (!m) {\ - m = stream->frame_size;\ - while (key->ptr < key->frame_size)\ - if (!eread_stream(key, key->frame_size - key->ptr))\ - return;\ - keyxyza = (TYPE *)(key->buf);\ - x1 = keyxyza[0];\ - y1 = keyxyza[1];\ - z1 = keyxyza[2];\ - a1 = keyxyza[3];\ - x = x1 - keyxyza[4];\ - y = y1 - keyxyza[5];\ - z = z1 - keyxyza[6];\ - a2 = keyxyza[7];\ - variance2 = x * x + y * y + z * z;\ - /* TODO add more formulae: https://en.wikipedia.org/wiki/Color_difference */\ - if (a2 > a1) {\ - a1 = 1 - a1;\ - a2 = 1 - a2;\ - }\ - memmove(key->buf, key->buf + key->frame_size,\ - key->ptr -= key->frame_size);\ - }\ - n = MIN(stream->ptr, m) / stream->pixel_size;\ - for (i = 0; i < n; i++) {\ - x = ((TYPE *)(stream->buf))[4 * i + 0] - x1;\ - y = ((TYPE *)(stream->buf))[4 * i + 1] - y1;\ - z = ((TYPE *)(stream->buf))[4 * i + 2] - z1;\ - d = x * x + y * y + z * z;\ - if (d <= variance2) {\ - if (a1 == a2)\ - d = 0;\ - else\ - d = sqrt(d / variance2) * (a1 - a2) + a2;\ - ((TYPE *)(stream->buf))[4 * i + 3] *= d;\ - }\ - }\ - 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);\ - } - -PROCESS(double, lf) -PROCESS(float, f) +#define FILE "blind-chroma-key.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -89,3 +36,60 @@ main(int argc, char *argv[]) process(&stream, &key); return 0; } + +#else + +static void +PROCESS(struct stream *stream, struct stream *key) +{ + size_t i, n, m = 0; + TYPE x1, y1, z1, a1, a2, variance2, *keyxyza; + TYPE x, y, z, d; + do { + if (!m) { + m = stream->frame_size; + while (key->ptr < key->frame_size) + if (!eread_stream(key, key->frame_size - key->ptr)) + return; + keyxyza = (TYPE *)(key->buf); + x1 = keyxyza[0]; + y1 = keyxyza[1]; + z1 = keyxyza[2]; + a1 = keyxyza[3]; + x = x1 - keyxyza[4]; + y = y1 - keyxyza[5]; + z = z1 - keyxyza[6]; + a2 = keyxyza[7]; + variance2 = x * x + y * y + z * z; + /* TODO add more formulae: https://en.wikipedia.org/wiki/Color_difference */ + if (a2 > a1) { + a1 = 1 - a1; + a2 = 1 - a2; + } + memmove(key->buf, key->buf + key->frame_size, + key->ptr -= key->frame_size); + } + n = MIN(stream->ptr, m) / stream->pixel_size; + for (i = 0; i < n; i++) { + x = ((TYPE *)(stream->buf))[4 * i + 0] - x1; + y = ((TYPE *)(stream->buf))[4 * i + 1] - y1; + z = ((TYPE *)(stream->buf))[4 * i + 2] - z1; + d = x * x + y * y + z * z; + if (d <= variance2) { + if (a1 == a2) + d = 0; + else + d = sqrt(d / variance2) * (a1 - a2) + a2; + ((TYPE *)(stream->buf))[4 * i + 3] *= d; + } + } + 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); +} + +#endif diff --git a/src/blind-cone-gradient.c b/src/blind-cone-gradient.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-a | -s] -w width -h height") @@ -9,69 +10,8 @@ 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 - stream->ptr)) {\ - ewriteall(STDOUT_FILENO, buf, ptr * sizeof(*buf), "<stdout>");\ - 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;\ - if (!x && !y) {\ - v = 0.5;\ - } else {\ - 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] = buf[ptr][3] = v;\ - if (++ptr == ELEMENTSOF(buf)) {\ - ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>");\ - ptr = 0;\ - }\ - }\ - }\ - }\ - } - -PROCESS(double, lf) -PROCESS(float, f) +#define FILE "blind-cone-gradient.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -81,13 +21,9 @@ main(int argc, char *argv[]) ARGBEGIN { case 'a': - if (symmetric) - usage(); anticlockwise = 1; break; case 's': - if (anticlockwise) - usage(); symmetric = 1; break; case 'w': @@ -100,7 +36,7 @@ main(int argc, char *argv[]) usage(); } ARGEND; - if (!width || !height || argc) + if (!width || !height || (symmetric && anticlockwise) || argc) usage(); eopen_stream(&stream, NULL); @@ -126,3 +62,68 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(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 - stream->ptr)) { + ewriteall(STDOUT_FILENO, buf, ptr * sizeof(*buf), "<stdout>"); + 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; + if (!x && !y) { + v = 0.5; + } else { + 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] = buf[ptr][3] = v; + if (++ptr == ELEMENTSOF(buf)) { + ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>"); + ptr = 0; + } + } + } + } +} + +#endif diff --git a/src/blind-coordinate-field.c b/src/blind-coordinate-field.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-f frames | -f 'inf'] [-F pixel-format] -w width -h height") @@ -6,25 +7,8 @@ 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(buf)) < 0)\ - eprintf("write <stdout>:");\ - }\ - }\ - }\ - } while (0) - -static void process_lf(void) {PROCESS(double);} -static void process_f(void) {PROCESS(float);} +#define FILE "blind-coordinate-field.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -75,3 +59,24 @@ main(int argc, char *argv[]) process(); return 0; } + +#else + +static void +PROCESS(void) +{ + 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(buf)) < 0) + eprintf("write <stdout>:"); + } + } + } +} + +#endif diff --git a/src/blind-cross-product.c b/src/blind-cross-product.c @@ -1,32 +1,11 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("right-hand-stream") -#define PROCESS(TYPE, SUFFIX)\ - static void\ - process_##SUFFIX(struct stream *left, struct stream *right, size_t n)\ - {\ - size_t i;\ - TYPE *lx, *ly, *lz, *la, *rx, *ry, *rz, *ra, x, y, z, a;\ - for (i = 0; i < n; i += 4 * sizeof(TYPE)) {\ - lx = ((TYPE *)(left->buf + i)) + 0, rx = ((TYPE *)(right->buf + i)) + 0;\ - ly = ((TYPE *)(left->buf + i)) + 1, ry = ((TYPE *)(right->buf + i)) + 1;\ - lz = ((TYPE *)(left->buf + i)) + 2, rz = ((TYPE *)(right->buf + i)) + 2;\ - la = ((TYPE *)(left->buf + i)) + 3, ra = ((TYPE *)(right->buf + i)) + 3;\ - x = *ly * *rz - *lz * *ry;\ - y = *lz * *rx - *lx * *rz;\ - z = *lx * *ry - *ly * *rx;\ - a = *la * *ra;\ - *lx = x;\ - *ly = y;\ - *lz = z;\ - *la = a;\ - }\ - } - -PROCESS(double, lf) -PROCESS(float, f) +#define FILE "blind-cross-product.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -51,3 +30,28 @@ main(int argc, char *argv[]) process_two_streams(&left, &right, STDOUT_FILENO, "<stdout>", process); return 0; } + +#else + +static void +PROCESS(struct stream *left, struct stream *right, size_t n) +{ + size_t i; + TYPE *lx, *ly, *lz, *la, *rx, *ry, *rz, *ra, x, y, z, a; + for (i = 0; i < n; i += 4 * sizeof(TYPE)) { + lx = ((TYPE *)(left->buf + i)) + 0, rx = ((TYPE *)(right->buf + i)) + 0; + ly = ((TYPE *)(left->buf + i)) + 1, ry = ((TYPE *)(right->buf + i)) + 1; + lz = ((TYPE *)(left->buf + i)) + 2, rz = ((TYPE *)(right->buf + i)) + 2; + la = ((TYPE *)(left->buf + i)) + 3, ra = ((TYPE *)(right->buf + i)) + 3; + x = *ly * *rz - *lz * *ry; + y = *lz * *rx - *lx * *rz; + z = *lx * *ry - *ly * *rx; + a = *la * *ra; + *lx = x; + *ly = y; + *lz = z; + *la = a; + } +} + +#endif diff --git a/src/blind-dot-product.c b/src/blind-dot-product.c @@ -1,27 +1,11 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("right-hand-stream") -#define PROCESS(TYPE, SUFFIX)\ - static void\ - process_##SUFFIX(struct stream *left, struct stream *right, size_t n)\ - {\ - size_t i, j, s = left->n_chan * sizeof(TYPE);\ - TYPE v, *l, *r;\ - for (i = 0; i < n; i += s) {\ - l = (TYPE *)(left->buf + i);\ - r = (TYPE *)(right->buf + i);\ - v = 0;\ - for (j = 0; j < left->n_chan; j++)\ - v += l[j] * r[j];\ - for (j = 0; j < left->n_chan; j++)\ - l[j] = v;\ - }\ - } - -PROCESS(double, lf) -PROCESS(float, f) +#define FILE "blind-dot-product.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -46,3 +30,23 @@ main(int argc, char *argv[]) process_two_streams(&left, &right, STDOUT_FILENO, "<stdout>", process); return 0; } + +#else + +static void +PROCESS(struct stream *left, struct stream *right, size_t n) +{ + size_t i, j, s = left->n_chan * sizeof(TYPE); + TYPE v, *l, *r; + for (i = 0; i < n; i += s) { + l = (TYPE *)(left->buf + i); + r = (TYPE *)(right->buf + i); + v = 0; + for (j = 0; j < left->n_chan; j++) + v += l[j] * r[j]; + for (j = 0; j < left->n_chan; j++) + l[j] = v; + } +} + +#endif diff --git a/src/blind-double-sine-wave.c b/src/blind-double-sine-wave.c @@ -1,47 +1,13 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-e]") static int equal = 0; -#define PROCESS(TYPE, SUFFIX)\ - static void\ - process_##SUFFIX(struct stream *stream)\ - {\ - size_t i, j, n;\ - TYPE v, *p;\ - do {\ - if (equal) {\ - n = stream->ptr / stream->pixel_size;\ - for (i = 0; i < n; i++) {\ - p = (TYPE *)(stream->buf) + i * stream->n_chan;\ - v = posmod(*p, (TYPE)2);\ - v = v > 1 ? 2 - v : v;\ - v = 1 - (sin(v * (2 * (TYPE)M_PI)) + 1) / 2;\ - for (j = 0; j < stream->n_chan; j++)\ - p[j] = v;\ - }\ - n *= stream->pixel_size;\ - } else {\ - n = stream->ptr / stream->chan_size;\ - for (i = 0; i < n; i++) {\ - p = (TYPE *)(stream->buf) + i;\ - v = posmod(*p, (TYPE)2);\ - v = v > 1 ? 2 - v : v;\ - *p = 1 - (sin(v * (2 * (TYPE)M_PI)) + 1) / 2;\ - }\ - n *= stream->chan_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) +#define FILE "blind-double-sine-wave.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -74,3 +40,41 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(struct stream *stream) +{ + size_t i, j, n; + TYPE v, *p; + do { + if (equal) { + n = stream->ptr / stream->pixel_size; + for (i = 0; i < n; i++) { + p = (TYPE *)(stream->buf) + i * stream->n_chan; + v = posmod(*p, (TYPE)2); + v = v > 1 ? 2 - v : v; + v = 1 - (sin(v * (2 * (TYPE)M_PI)) + 1) / 2; + for (j = 0; j < stream->n_chan; j++) + p[j] = v; + } + n *= stream->pixel_size; + } else { + n = stream->ptr / stream->chan_size; + for (i = 0; i < n; i++) { + p = (TYPE *)(stream->buf) + i; + v = posmod(*p, (TYPE)2); + v = v > 1 ? 2 - v : v; + *p = 1 - (sin(v * (2 * (TYPE)M_PI)) + 1) / 2; + } + n *= stream->chan_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); +} + +#endif diff --git a/src/blind-dual-key.c b/src/blind-dual-key.c @@ -1,52 +1,13 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-m] X Y Z dual-X dual-Y dual-Z dual-stream") static double X1, Y1, Z1, X2, Y2, Z2; -#define PROCESS(TYPE)\ - do {\ - size_t i;\ - TYPE x1k = (TYPE)X1, y1k = (TYPE)Y1, z1k = (TYPE)Z1;\ - TYPE x2k = (TYPE)X2, y2k = (TYPE)Y2, z2k = (TYPE)Z2;\ - TYPE x1, y1, z1, a1, x2, y2, z2, a2;\ - TYPE alpha, xalpha, yalpha, zalpha;\ - for (i = 0; i < n; i += stream->pixel_size) {\ - x1 = ((TYPE *)(stream->buf + i))[0];\ - y1 = ((TYPE *)(stream->buf + i))[1];\ - z1 = ((TYPE *)(stream->buf + i))[2];\ - a1 = ((TYPE *)(stream->buf + i))[3];\ - x2 = ((TYPE *)(dual->buf + i))[0];\ - y2 = ((TYPE *)(dual->buf + i))[1];\ - z2 = ((TYPE *)(dual->buf + i))[2];\ - a2 = ((TYPE *)(dual->buf + i))[3];\ - if (x1 == x2 && y1 == y2 && z1 == z2) {\ - if (a1 != a2)\ - ((TYPE *)(stream->buf + i))[3] = (a1 + a2) / 2;\ - continue;\ - }\ - xalpha = x1 == x2 ? (TYPE)0 : (x2 - x1 + x1k - x2k) / (x1k - x2k);\ - yalpha = y1 == y2 ? (TYPE)0 : (y2 - y1 + y1k - y2k) / (y1k - y2k);\ - zalpha = z1 == z2 ? (TYPE)0 : (z2 - z1 + z1k - z2k) / (z1k - z2k);\ - alpha = xalpha > yalpha ? xalpha : yalpha;\ - alpha = alpha > zalpha ? alpha : zalpha;\ - if (!alpha) {\ - ((TYPE *)(stream->buf + i))[0] = (TYPE)0;\ - ((TYPE *)(stream->buf + i))[1] = (TYPE)0;\ - ((TYPE *)(stream->buf + i))[2] = (TYPE)0;\ - ((TYPE *)(stream->buf + i))[3] = (TYPE)0;\ - } else {\ - ((TYPE *)(stream->buf + i))[0] = ((x1 - x1k + x2 - x2k) / alpha + x1k + x2k) / 2;\ - ((TYPE *)(stream->buf + i))[1] = ((y1 - y1k + y2 - y2k) / alpha + y1k + y2k) / 2;\ - ((TYPE *)(stream->buf + i))[2] = ((z1 - z1k + z2 - z2k) / alpha + z1k + z2k) / 2;\ - ((TYPE *)(stream->buf + i))[3] = (a1 + a2) / 2 * alpha;\ - }\ - }\ - } while (0) - -static void process_lf(struct stream *stream, struct stream *dual, size_t n) {PROCESS(double);} -static void process_f (struct stream *stream, struct stream *dual, size_t n) {PROCESS(float);} +#define FILE "blind-dual-key.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -79,3 +40,48 @@ main(int argc, char *argv[]) process_two_streams(&stream, &dual, STDOUT_FILENO, "<stdout>", process); return 0; } + +#else + +static void +PROCESS(struct stream *stream, struct stream *dual, size_t n) +{ + size_t i; + TYPE x1k = (TYPE)X1, y1k = (TYPE)Y1, z1k = (TYPE)Z1; + TYPE x2k = (TYPE)X2, y2k = (TYPE)Y2, z2k = (TYPE)Z2; + TYPE x1, y1, z1, a1, x2, y2, z2, a2; + TYPE alpha, xalpha, yalpha, zalpha; + for (i = 0; i < n; i += stream->pixel_size) { + x1 = ((TYPE *)(stream->buf + i))[0]; + y1 = ((TYPE *)(stream->buf + i))[1]; + z1 = ((TYPE *)(stream->buf + i))[2]; + a1 = ((TYPE *)(stream->buf + i))[3]; + x2 = ((TYPE *)(dual->buf + i))[0]; + y2 = ((TYPE *)(dual->buf + i))[1]; + z2 = ((TYPE *)(dual->buf + i))[2]; + a2 = ((TYPE *)(dual->buf + i))[3]; + if (x1 == x2 && y1 == y2 && z1 == z2) { + if (a1 != a2) + ((TYPE *)(stream->buf + i))[3] = (a1 + a2) / 2; + continue; + } + xalpha = x1 == x2 ? (TYPE)0 : (x2 - x1 + x1k - x2k) / (x1k - x2k); + yalpha = y1 == y2 ? (TYPE)0 : (y2 - y1 + y1k - y2k) / (y1k - y2k); + zalpha = z1 == z2 ? (TYPE)0 : (z2 - z1 + z1k - z2k) / (z1k - z2k); + alpha = xalpha > yalpha ? xalpha : yalpha; + alpha = alpha > zalpha ? alpha : zalpha; + if (!alpha) { + ((TYPE *)(stream->buf + i))[0] = (TYPE)0; + ((TYPE *)(stream->buf + i))[1] = (TYPE)0; + ((TYPE *)(stream->buf + i))[2] = (TYPE)0; + ((TYPE *)(stream->buf + i))[3] = (TYPE)0; + } else { + ((TYPE *)(stream->buf + i))[0] = ((x1 - x1k + x2 - x2k) / alpha + x1k + x2k) / 2; + ((TYPE *)(stream->buf + i))[1] = ((y1 - y1k + y2 - y2k) / alpha + y1k + y2k) / 2; + ((TYPE *)(stream->buf + i))[2] = ((z1 - z1k + z2 - z2k) / alpha + z1k + z2k) / 2; + ((TYPE *)(stream->buf + i))[3] = (a1 + a2) / 2 * alpha; + } + } +} + +#endif diff --git a/src/blind-extract-alpha.c b/src/blind-extract-alpha.c @@ -1,36 +1,11 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("colour-file") -#define PROCESS(TYPE, SUFFIX)\ - static void\ - process_##SUFFIX(struct stream *stream, int fd, const char *fname)\ - {\ - char buf[sizeof(stream->buf)];\ - size_t i, j, n;\ - TYPE a, *p, *b;\ - do {\ - n = stream->ptr / stream->pixel_size;\ - p = (TYPE *)(stream->buf) + stream->n_chan - 1;\ - b = (TYPE *)buf;\ - for (i = 0; i < n; i++, p += stream->n_chan) {\ - a = *p, *p = 1;\ - for (j = stream->n_chan - 1; j--;)\ - *b++ = a;\ - *b++ = 1;\ - }\ - n *= stream->pixel_size;\ - ewriteall(fd, stream->buf, n, fname);\ - ewriteall(STDOUT_FILENO, 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) +#define FILE "blind-extract-alpha.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -59,3 +34,32 @@ main(int argc, char *argv[]) process(&stream, fd, argv[0]); return 0; } + +#else + +static void +PROCESS(struct stream *stream, int fd, const char *fname) +{ + char buf[sizeof(stream->buf)]; + size_t i, j, n; + TYPE a, *p, *b; + do { + n = stream->ptr / stream->pixel_size; + p = (TYPE *)(stream->buf) + stream->n_chan - 1; + b = (TYPE *)buf; + for (i = 0; i < n; i++, p += stream->n_chan) { + a = *p, *p = 1; + for (j = stream->n_chan - 1; j--;) + *b++ = a; + *b++ = 1; + } + n *= stream->pixel_size; + ewriteall(fd, stream->buf, n, fname); + ewriteall(STDOUT_FILENO, 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); +} + +#endif diff --git a/src/blind-invert-matrix.c b/src/blind-invert-matrix.c @@ -1,62 +1,20 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("") static int equal = 0; -#define SUB_ROWS()\ - do {\ - p2 = matrix + r2 * cn;\ - t = p2[r1][0];\ - for (c = 0; c < cn; c++)\ - p2[c][0] -= p1[c][0] * t;\ - } while (0) - -#define PROCESS(TYPE)\ - do {\ - typedef TYPE pixel_t[4];\ - size_t rn = stream->height, r1, r2, c;\ - size_t cn = stream->width > rn ? stream->width : 2 * rn;\ - pixel_t *matrix = buf, *p1, *p2;\ - TYPE t;\ - \ - for (r1 = 0; r1 < rn; r1++) {\ - p1 = matrix + r1 * cn;\ - if (!p1[r1][0]) {\ - for (r2 = r1 + 1; r2 < rn; r2++) {\ - p2 = matrix + r2 * cn;\ - if (p2[r1][0])\ - break;\ - }\ - if (r2 >= rn)\ - eprintf("matrix is not invertable\n");\ - for (c = 0; c < cn; c++)\ - t = p1[c][0], p1[c][0] = p2[c][0], p2[c][0] = t;\ - }\ - t = 1 / p1[r1][0];\ - for (c = 0; c < cn; c++)\ - p1[c][0] *= t;\ - for (r2 = r1 + 1; r2 < rn; r2++)\ - SUB_ROWS();\ - }\ - \ - for (r1 = rn; r1--;) {\ - p1 = matrix + r1 * cn;\ - for (r2 = r1; r2--;)\ - SUB_ROWS();\ - }\ - } while (0) - -static void process_lf(struct stream *stream, void *buf) { PROCESS(double); } -static void process_f (struct stream *stream, void *buf) { PROCESS(float); } +#define FILE "blind-invert-matrix.c" +#include "define-functions.h" int main(int argc, char *argv[]) { struct stream stream; - size_t width, x, y, row_size; - char *buf, *one = alloca(4 * sizeof(double)), *p; + size_t width, x, y, i, row_size; + char *buf, *one, *p; void (*process)(struct stream *stream, void *buf); ARGBEGIN { @@ -92,9 +50,8 @@ main(int argc, char *argv[]) eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt); } - memcpy(one + 1 * stream.chan_size, one, stream.chan_size); - memcpy(one + 2 * stream.chan_size, one, stream.chan_size); - memcpy(one + 3 * stream.chan_size, one, stream.chan_size); + for (i = 1; i < stream.n_chan; i++) + memcpy(one + i * stream.chan_size, one, stream.chan_size); width = stream.width > stream.height ? stream.width : 2 * stream.height; buf = emalloc2(width, stream.col_size); @@ -109,19 +66,17 @@ main(int argc, char *argv[]) } } if (equal) { - process(&stream, buf + 1 * stream.chan_size); + process(&stream, buf); for (y = 0; y < stream.height; y++) { for (x = 0; x < stream.width; x++) { p = buf + y * row_size + x * stream.pixel_size; - memcpy(p, p + stream.chan_size, stream.chan_size); - memcpy(p + 2 * stream.chan_size, p, 2 * stream.chan_size); + for (i = 1; i < stream.n_chan; i++) + memcpy(p + i * stream.chan_size, p, stream.chan_size); } } } else { - process(&stream, buf + 0 * stream.chan_size); - process(&stream, buf + 1 * stream.chan_size); - process(&stream, buf + 2 * stream.chan_size); - process(&stream, buf + 3 * stream.chan_size); + for (i = 0; i < stream.n_chan; i++) + process(&stream, buf + i * stream.chan_size); } for (y = 0; y < stream.height; y++) ewriteall(STDOUT_FILENO, buf + y * row_size + stream.col_size, row_size - stream.col_size, "<stdout>"); @@ -130,3 +85,52 @@ main(int argc, char *argv[]) free(buf); return 0; } + +#else + +#define SUB_ROWS()\ + do {\ + p2 = matrix + r2 * cn;\ + t = p2[r1][0];\ + for (c = 0; c < cn; c++)\ + p2[c][0] -= p1[c][0] * t;\ + } while (0) + +static void +PROCESS(struct stream *stream, void *buf) +{ + typedef TYPE pixel_t[4]; + size_t rn = stream->height, r1, r2, c; + size_t cn = stream->width > rn ? stream->width : 2 * rn; + pixel_t *matrix = buf, *p1, *p2; + TYPE t; + + for (r1 = 0; r1 < rn; r1++) { + p1 = matrix + r1 * cn; + if (!p1[r1][0]) { + for (r2 = r1 + 1; r2 < rn; r2++) { + p2 = matrix + r2 * cn; + if (p2[r1][0]) + break; + } + if (r2 >= rn) + eprintf("matrix is not invertable\n"); + for (c = 0; c < cn; c++) + t = p1[c][0], p1[c][0] = p2[c][0], p2[c][0] = t; + } + t = 1 / p1[r1][0]; + for (c = 0; c < cn; c++) + p1[c][0] *= t; + for (r2 = r1 + 1; r2 < rn; r2++) + SUB_ROWS(); + } + + for (r1 = rn; r1--;) { + p1 = matrix + r1 * cn; + for (r2 = r1; r2--;) + SUB_ROWS(); + } +} + +#undef SUB_ROWS +#endif diff --git a/src/blind-linear-gradient.c b/src/blind-linear-gradient.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-b] -w width -h height") @@ -7,53 +8,8 @@ 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 - stream->ptr)) {\ - ewriteall(STDOUT_FILENO, buf, ptr * sizeof(*buf), "<stdout>");\ - 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] = buf[ptr][3] = x;\ - if (++ptr == ELEMENTSOF(buf)) {\ - ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>");\ - ptr = 0;\ - }\ - }\ - }\ - }\ - } - -PROCESS(double, lf) -PROCESS(float, f) +#define FILE "blind-linear-gradient.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -97,3 +53,52 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(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 - stream->ptr)) { + ewriteall(STDOUT_FILENO, buf, ptr * sizeof(*buf), "<stdout>"); + 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] = buf[ptr][3] = x; + if (++ptr == ELEMENTSOF(buf)) { + ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>"); + ptr = 0; + } + } + } + } +} + +#endif diff --git a/src/blind-matrix-orthoproject.c b/src/blind-matrix-orthoproject.c @@ -1,56 +1,13 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-c]") static int per_channel = 0; -#define PROCESS(TYPE)\ - do {\ - typedef TYPE pixel_t[4];\ - pixel_t matrix[9];\ - pixel_t buf[2];\ - TYPE x2, y2, norm2;\ - size_t i;\ - \ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\ - matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\ - matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\ - }\ - \ - while (eread_frame(stream, buf)) {\ - if (per_channel) {\ - for (i = 0; i < stream->n_chan; i++) {\ - x2 = buf[0][i] * buf[0][i];\ - y2 = buf[1][i] * buf[1][i];\ - norm2 = x2 + y2;\ - matrix[0][i] = x2 / norm2;\ - matrix[4][i] = y2 / norm2;\ - matrix[3][i] = matrix[1][i] = buf[0][i] * buf[1][i] / norm2;\ - }\ - } else {\ - buf[0][1] *= buf[0][3];\ - buf[1][1] *= buf[1][3];\ - x2 = buf[0][1] * buf[0][1];\ - y2 = buf[1][1] * buf[1][1];\ - norm2 = x2 + y2;\ - matrix[0][0] = x2 / norm2;\ - matrix[4][0] = y2 / norm2;\ - matrix[3][0] = matrix[1][0] = buf[0][1] * buf[1][1] / norm2;\ - for (i = 1; i < stream->n_chan; i++) {\ - matrix[0][i] = matrix[0][0];\ - matrix[1][i] = matrix[1][0];\ - matrix[3][i] = matrix[3][0];\ - matrix[4][i] = matrix[4][0];\ - }\ - }\ - ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");\ - }\ - } while (0) - -static void process_lf(struct stream *stream) { PROCESS(double); } -static void process_f(struct stream *stream) { PROCESS(float); } +#define FILE "blind-matrix-orthoproject.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -89,3 +46,52 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(struct stream *stream) +{ + typedef TYPE pixel_t[4]; + pixel_t matrix[9]; + pixel_t buf[2]; + TYPE x2, y2, norm2; + size_t i; + + for (i = 0; i < stream->n_chan; i++) { + matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0; + matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0; + matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1; + } + + while (eread_frame(stream, buf)) { + if (per_channel) { + for (i = 0; i < stream->n_chan; i++) { + x2 = buf[0][i] * buf[0][i]; + y2 = buf[1][i] * buf[1][i]; + norm2 = x2 + y2; + matrix[0][i] = x2 / norm2; + matrix[4][i] = y2 / norm2; + matrix[3][i] = matrix[1][i] = buf[0][i] * buf[1][i] / norm2; + } + } else { + buf[0][1] *= buf[0][3]; + buf[1][1] *= buf[1][3]; + x2 = buf[0][1] * buf[0][1]; + y2 = buf[1][1] * buf[1][1]; + norm2 = x2 + y2; + matrix[0][0] = x2 / norm2; + matrix[4][0] = y2 / norm2; + matrix[3][0] = matrix[1][0] = buf[0][1] * buf[1][1] / norm2; + for (i = 1; i < stream->n_chan; i++) { + matrix[0][i] = matrix[0][0]; + matrix[1][i] = matrix[1][0]; + matrix[3][i] = matrix[3][0]; + matrix[4][i] = matrix[4][0]; + } + } + ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>"); + } +} + +#endif diff --git a/src/blind-matrix-reflect.c b/src/blind-matrix-reflect.c @@ -1,54 +1,13 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-c]") static int per_channel = 0; -#define PROCESS(TYPE)\ - do {\ - typedef TYPE pixel_t[4];\ - pixel_t matrix[9];\ - pixel_t buf[2];\ - TYPE x2, y2, norm2;\ - size_t i;\ - \ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\ - matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\ - matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\ - }\ - \ - while (eread_frame(stream, buf)) {\ - if (per_channel) {\ - for (i = 0; i < stream->n_chan; i++) {\ - x2 = buf[0][i] * buf[0][i];\ - y2 = buf[1][i] * buf[1][i];\ - norm2 = x2 + y2;\ - matrix[4][i] = -(matrix[0][i] = (x2 - y2) / norm2);\ - matrix[3][i] = matrix[1][i] = 2 * buf[0][i] * buf[1][i] / norm2;\ - }\ - } else {\ - buf[0][1] *= buf[0][3];\ - buf[1][1] *= buf[1][3];\ - x2 = buf[0][1] * buf[0][1];\ - y2 = buf[1][1] * buf[1][1];\ - norm2 = x2 + y2;\ - matrix[4][0] = -(matrix[0][0] = (x2 - y2) / norm2);\ - matrix[3][0] = matrix[1][0] = 2 * buf[0][1] * buf[1][1] / norm2;\ - for (i = 1; i < stream->n_chan; i++) {\ - matrix[0][i] = matrix[0][0];\ - matrix[1][i] = matrix[1][0];\ - matrix[3][i] = matrix[3][0];\ - matrix[4][i] = matrix[4][0];\ - }\ - }\ - ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");\ - }\ - } while (0) - -static void process_lf(struct stream *stream) { PROCESS(double); } -static void process_f(struct stream *stream) { PROCESS(float); } +#define FILE "blind-matrix-reflect.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -87,3 +46,50 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(struct stream *stream) +{ + typedef TYPE pixel_t[4]; + pixel_t matrix[9]; + pixel_t buf[2]; + TYPE x2, y2, norm2; + size_t i; + + for (i = 0; i < stream->n_chan; i++) { + matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0; + matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0; + matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1; + } + + while (eread_frame(stream, buf)) { + if (per_channel) { + for (i = 0; i < stream->n_chan; i++) { + x2 = buf[0][i] * buf[0][i]; + y2 = buf[1][i] * buf[1][i]; + norm2 = x2 + y2; + matrix[4][i] = -(matrix[0][i] = (x2 - y2) / norm2); + matrix[3][i] = matrix[1][i] = 2 * buf[0][i] * buf[1][i] / norm2; + } + } else { + buf[0][1] *= buf[0][3]; + buf[1][1] *= buf[1][3]; + x2 = buf[0][1] * buf[0][1]; + y2 = buf[1][1] * buf[1][1]; + norm2 = x2 + y2; + matrix[4][0] = -(matrix[0][0] = (x2 - y2) / norm2); + matrix[3][0] = matrix[1][0] = 2 * buf[0][1] * buf[1][1] / norm2; + for (i = 1; i < stream->n_chan; i++) { + matrix[0][i] = matrix[0][0]; + matrix[1][i] = matrix[1][0]; + matrix[3][i] = matrix[3][0]; + matrix[4][i] = matrix[4][0]; + } + } + ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>"); + } +} + +#endif diff --git a/src/blind-matrix-rotate.c b/src/blind-matrix-rotate.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-cd]") @@ -6,52 +7,8 @@ USAGE("[-cd]") static int per_channel = 0; static int in_degrees = 0; -#define PROCESS(TYPE)\ - do {\ - typedef TYPE pixel_t[4];\ - pixel_t matrix[9];\ - pixel_t buf;\ - size_t i;\ - \ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\ - matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\ - matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\ - }\ - \ - while (eread_frame(stream, buf)) {\ - if (per_channel && in_degrees) {\ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[4][i] = matrix[0][i] = degcos(buf[i]);\ - matrix[3][i] = -(matrix[1][i] = degsin(buf[i]));\ - }\ - } else if (per_channel) {\ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[4][i] = matrix[0][i] = cos(buf[i]);\ - matrix[3][i] = -(matrix[1][i] = sin(buf[i]));\ - }\ - } else {\ - buf[1] *= buf[3];\ - if (in_degrees) {\ - matrix[4][0] = matrix[0][0] = degcos(buf[1]);\ - matrix[3][0] = -(matrix[1][0] = degsin(buf[1]));\ - } else {\ - matrix[4][0] = matrix[0][0] = cos(buf[1]);\ - matrix[3][0] = -(matrix[1][0] = sin(buf[1]));\ - }\ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[0][i] = matrix[0][0];\ - matrix[1][i] = matrix[1][0];\ - matrix[3][i] = matrix[3][0];\ - matrix[4][i] = matrix[4][0];\ - }\ - }\ - ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");\ - }\ - } while (0) - -static void process_lf(struct stream *stream) { PROCESS(double); } -static void process_f(struct stream *stream) { PROCESS(float); } +#define FILE "blind-matrix-rotate.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -93,3 +50,52 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(struct stream *stream) +{ + typedef TYPE pixel_t[4]; + pixel_t matrix[9]; + pixel_t buf; + size_t i; + + for (i = 0; i < stream->n_chan; i++) { + matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0; + matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0; + matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1; + } + + while (eread_frame(stream, buf)) { + if (per_channel && in_degrees) { + for (i = 0; i < stream->n_chan; i++) { + matrix[4][i] = matrix[0][i] = degcos(buf[i]); + matrix[3][i] = -(matrix[1][i] = degsin(buf[i])); + } + } else if (per_channel) { + for (i = 0; i < stream->n_chan; i++) { + matrix[4][i] = matrix[0][i] = cos(buf[i]); + matrix[3][i] = -(matrix[1][i] = sin(buf[i])); + } + } else { + buf[1] *= buf[3]; + if (in_degrees) { + matrix[4][0] = matrix[0][0] = degcos(buf[1]); + matrix[3][0] = -(matrix[1][0] = degsin(buf[1])); + } else { + matrix[4][0] = matrix[0][0] = cos(buf[1]); + matrix[3][0] = -(matrix[1][0] = sin(buf[1])); + } + for (i = 0; i < stream->n_chan; i++) { + matrix[0][i] = matrix[0][0]; + matrix[1][i] = matrix[1][0]; + matrix[3][i] = matrix[3][0]; + matrix[4][i] = matrix[4][0]; + } + } + ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>"); + } +} + +#endif diff --git a/src/blind-matrix-scale.c b/src/blind-matrix-scale.c @@ -1,43 +1,13 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-c]") static int per_channel = 0; -#define PROCESS(TYPE)\ - do {\ - typedef TYPE pixel_t[4];\ - pixel_t matrix[9];\ - pixel_t buf[2];\ - size_t i;\ - \ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\ - matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\ - matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\ - }\ - \ - while (eread_frame(stream, buf)) {\ - if (per_channel) {\ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[0][i] = buf[0][i];\ - matrix[4][i] = buf[1][i];\ - }\ - } else {\ - buf[0][1] *= buf[0][3];\ - buf[1][1] *= buf[1][3];\ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[0][i] = buf[0][1];\ - matrix[4][i] = buf[1][1];\ - }\ - }\ - ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");\ - }\ - } while (0) - -static void process_lf(struct stream *stream) { PROCESS(double); } -static void process_f(struct stream *stream) { PROCESS(float); } +#define FILE "blind-matrix-scale.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -76,3 +46,39 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(struct stream *stream) +{ + typedef TYPE pixel_t[4]; + pixel_t matrix[9]; + pixel_t buf[2]; + size_t i; + + for (i = 0; i < stream->n_chan; i++) { + matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0; + matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0; + matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1; + } + + while (eread_frame(stream, buf)) { + if (per_channel) { + for (i = 0; i < stream->n_chan; i++) { + matrix[0][i] = buf[0][i]; + matrix[4][i] = buf[1][i]; + } + } else { + buf[0][1] *= buf[0][3]; + buf[1][1] *= buf[1][3]; + for (i = 0; i < stream->n_chan; i++) { + matrix[0][i] = buf[0][1]; + matrix[4][i] = buf[1][1]; + } + } + ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>"); + } +} + +#endif diff --git a/src/blind-matrix-shear.c b/src/blind-matrix-shear.c @@ -1,52 +1,15 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" -USAGE("[-a [-d]][c]") +USAGE("[-a [-d]] [-c]") static int by_angle = 0; static int per_channel = 0; static int in_degrees = 0; -#define PROCESS(TYPE)\ - do {\ - typedef TYPE pixel_t[4];\ - pixel_t matrix[9];\ - pixel_t buf[2];\ - TYPE conv = in_degrees ? (TYPE)(M_PI / 180.) : 1;\ - size_t i;\ - \ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\ - matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\ - matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\ - }\ - \ - while (eread_frame(stream, buf)) {\ - if (by_angle) {\ - for (i = !per_channel; i < (per_channel ? stream->n_chan : 2); i++) {\ - buf[0][i] = tan(buf[0][i] * conv);\ - buf[1][i] = tan(buf[1][i] * conv);\ - }\ - }\ - if (per_channel) {\ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[1][i] = buf[0][i];\ - matrix[3][i] = buf[1][i];\ - }\ - } else {\ - buf[0][1] *= buf[0][3];\ - buf[1][1] *= buf[1][3];\ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[1][i] = buf[0][1];\ - matrix[3][i] = buf[1][1];\ - }\ - }\ - ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");\ - }\ - } while (0) - -static void process_lf(struct stream *stream) { PROCESS(double); } -static void process_f(struct stream *stream) { PROCESS(float); } +#define FILE "blind-matrix-shear.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -91,3 +54,46 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(struct stream *stream) +{ + typedef TYPE pixel_t[4]; + pixel_t matrix[9]; + pixel_t buf[2]; + TYPE conv = in_degrees ? (TYPE)(M_PI / 180.) : 1; + size_t i; + + for (i = 0; i < stream->n_chan; i++) { + matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0; + matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0; + matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1; + } + + while (eread_frame(stream, buf)) { + if (by_angle) { + for (i = !per_channel; i < (per_channel ? stream->n_chan : 2); i++) { + buf[0][i] = tan(buf[0][i] * conv); + buf[1][i] = tan(buf[1][i] * conv); + } + } + if (per_channel) { + for (i = 0; i < stream->n_chan; i++) { + matrix[1][i] = buf[0][i]; + matrix[3][i] = buf[1][i]; + } + } else { + buf[0][1] *= buf[0][3]; + buf[1][1] *= buf[1][3]; + for (i = 0; i < stream->n_chan; i++) { + matrix[1][i] = buf[0][1]; + matrix[3][i] = buf[1][1]; + } + } + ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>"); + } +} + +#endif diff --git a/src/blind-matrix-translate.c b/src/blind-matrix-translate.c @@ -1,43 +1,13 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-c]") static int per_channel = 0; -#define PROCESS(TYPE)\ - do {\ - typedef TYPE pixel_t[4];\ - pixel_t matrix[9];\ - pixel_t buf[2];\ - size_t i;\ - \ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\ - matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\ - matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\ - }\ - \ - while (eread_frame(stream, buf)) {\ - if (per_channel) {\ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[2][i] = buf[0][i];\ - matrix[5][i] = buf[1][i];\ - }\ - } else {\ - buf[0][1] *= buf[0][3];\ - buf[1][1] *= buf[1][3];\ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[2][i] = buf[0][1];\ - matrix[5][i] = buf[1][1];\ - }\ - }\ - ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");\ - }\ - } while (0) - -static void process_lf(struct stream *stream) { PROCESS(double); } -static void process_f(struct stream *stream) { PROCESS(float); } +#define FILE "blind-matrix-translate.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -76,3 +46,39 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(struct stream *stream) +{ + typedef TYPE pixel_t[4]; + pixel_t matrix[9]; + pixel_t buf[2]; + size_t i; + + for (i = 0; i < stream->n_chan; i++) { + matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0; + matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0; + matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1; + } + + while (eread_frame(stream, buf)) { + if (per_channel) { + for (i = 0; i < stream->n_chan; i++) { + matrix[2][i] = buf[0][i]; + matrix[5][i] = buf[1][i]; + } + } else { + buf[0][1] *= buf[0][3]; + buf[1][1] *= buf[1][3]; + for (i = 0; i < stream->n_chan; i++) { + matrix[2][i] = buf[0][1]; + matrix[5][i] = buf[1][1]; + } + } + ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>"); + } +} + +#endif diff --git a/src/blind-matrix-transpose.c b/src/blind-matrix-transpose.c @@ -1,42 +1,13 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-c]") static int per_channel = 0; -#define PROCESS(TYPE)\ - do {\ - typedef TYPE pixel_t[4];\ - pixel_t matrix[9];\ - pixel_t buf;\ - size_t i;\ - \ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0;\ - matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0;\ - matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1;\ - }\ - \ - while (eread_frame(stream, buf)) {\ - if (per_channel) {\ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[3][i] = matrix[1][i] = buf[i];\ - matrix[4][i] = matrix[0][i] = 1 - buf[i];\ - }\ - } else {\ - buf[1] *= buf[3];\ - for (i = 0; i < stream->n_chan; i++) {\ - matrix[3][i] = matrix[1][i] = buf[1];\ - matrix[4][i] = matrix[0][i] = 1 - matrix[3][i];\ - }\ - }\ - ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>");\ - }\ - } while (0) - -static void process_lf(struct stream *stream) { PROCESS(double); } -static void process_f(struct stream *stream) { PROCESS(float); } +#define FILE "blind-matrix-transpose.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -75,3 +46,38 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(struct stream *stream) +{ + typedef TYPE pixel_t[4]; + pixel_t matrix[9]; + pixel_t buf; + size_t i; + + for (i = 0; i < stream->n_chan; i++) { + matrix[0][i] = 1, matrix[1][i] = 0, matrix[2][i] = 0; + matrix[3][i] = 0, matrix[4][i] = 1, matrix[5][i] = 0; + matrix[6][i] = 0, matrix[7][i] = 0, matrix[8][i] = 1; + } + + while (eread_frame(stream, buf)) { + if (per_channel) { + for (i = 0; i < stream->n_chan; i++) { + matrix[3][i] = matrix[1][i] = buf[i]; + matrix[4][i] = matrix[0][i] = 1 - buf[i]; + } + } else { + buf[1] *= buf[3]; + for (i = 0; i < stream->n_chan; i++) { + matrix[3][i] = matrix[1][i] = buf[1]; + matrix[4][i] = matrix[0][i] = 1 - matrix[3][i]; + } + } + ewriteall(STDOUT_FILENO, matrix, sizeof(matrix), "<stdout>"); + } +} + +#endif diff --git a/src/blind-multiply-matrices.c b/src/blind-multiply-matrices.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-en] leftmost-stream ... rightmost-stream") @@ -6,56 +7,8 @@ USAGE("[-en] leftmost-stream ... rightmost-stream") static int equal = 0; static size_t max_frame_size; -#define PROCESS(TYPE)\ - do {\ - typedef TYPE pixel_t[4];\ - pixel_t *res, *left, *right, *tmp;\ - size_t i, j, w, h, h2, x, y, k, r;\ - res = emalloc(max_frame_size);\ - left = emalloc(max_frame_size);\ - right = emalloc(max_frame_size);\ - \ - while (eread_frame(streams + (n_streams - 1), res)) {\ - w = streams[n_streams - 1].width;\ - h = streams[n_streams - 1].height;\ - for (i = n_streams - 1; i--;) {\ - tmp = res, res = right, right = tmp;\ - if (!eread_frame(streams + i, left))\ - goto done;\ - h2 = streams[i].height;\ - memset(res, 0, w * h2 * streams->pixel_size);\ - \ - /* XXX Is there any significant performance to be gained by transposing `right`? */\ - if (equal) {\ - for (y = r = 0; y < h2; y++) {\ - for (x = 0; x < w; x++, r++) {\ - for (k = 0; k < h; k++) \ - res[r][0] += left[y * h + k][0] * right[k * w + x][0];\ - for (j = 1; j < streams->n_chan; j++)\ - res[r][j] = res[r][0];\ - }\ - }\ - } else {\ - for (y = r = 0; y < h2; y++)\ - for (x = 0; x < w; x++, r++) \ - for (k = 0; k < h; k++)\ - for (j = 0; j < streams->n_chan; j++)\ - res[r][j] += left[y * h + k][j] * right[k * w + x][j];\ - }\ - \ - h = h2;\ - }\ - ewriteall(STDOUT_FILENO, res, streams->frame_size, "<stdout>");\ - }\ - \ - done:\ - free(res);\ - free(left);\ - free(right);\ - } while (0) - -static void process_lf(struct stream *streams, size_t n_streams) { PROCESS(double); } -static void process_f (struct stream *streams, size_t n_streams) { PROCESS(float); } +#define FILE "blind-multiply-matrices.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -137,3 +90,56 @@ main(int argc, char *argv[]) free(streams); return 0; } + +#else + +static void +PROCESS(struct stream *streams, size_t n_streams) +{ + typedef TYPE pixel_t[4]; + pixel_t *res, *left, *right, *tmp; + size_t i, j, w, h, h2, x, y, k, r; + res = emalloc(max_frame_size); + left = emalloc(max_frame_size); + right = emalloc(max_frame_size); + + while (eread_frame(streams + (n_streams - 1), res)) { + w = streams[n_streams - 1].width; + h = streams[n_streams - 1].height; + for (i = n_streams - 1; i--;) { + tmp = res, res = right, right = tmp; + if (!eread_frame(streams + i, left)) + goto done; + h2 = streams[i].height; + memset(res, 0, w * h2 * streams->pixel_size); + + /* XXX Is there any significant performance to be gained by transposing `right`? */ + if (equal) { + for (y = r = 0; y < h2; y++) { + for (x = 0; x < w; x++, r++) { + for (k = 0; k < h; k++) + res[r][0] += left[y * h + k][0] * right[k * w + x][0]; + for (j = 1; j < streams->n_chan; j++) + res[r][j] = res[r][0]; + } + } + } else { + for (y = r = 0; y < h2; y++) + for (x = 0; x < w; x++, r++) + for (k = 0; k < h; k++) + for (j = 0; j < streams->n_chan; j++) + res[r][j] += left[y * h + k][j] * right[k * w + x][j]; + } + + h = h2; + } + ewriteall(STDOUT_FILENO, res, streams->frame_size, "<stdout>"); + } + +done: + free(res); + free(left); + free(right); +} + +#endif diff --git a/src/blind-norm.c b/src/blind-norm.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-axyz]") @@ -8,39 +9,8 @@ static int skip_x = 0; static int skip_y = 0; static int skip_z = 0; -#define PROCESS(TYPE, SUFFIX)\ - static void\ - process_##SUFFIX(struct stream *stream)\ - {\ - size_t i, n;\ - TYPE x, y, z, a, norm;\ - do {\ - n = stream->ptr / stream->pixel_size;\ - 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];\ - norm = sqrt(x * x + y * y + z * z + a * a);\ - if (!skip_x)\ - ((TYPE *)(stream->buf))[4 * i + 0] = norm;\ - if (!skip_y)\ - ((TYPE *)(stream->buf))[4 * i + 1] = norm;\ - if (!skip_z)\ - ((TYPE *)(stream->buf))[4 * i + 2] = norm;\ - if (!skip_a)\ - ((TYPE *)(stream->buf))[4 * i + 3] = norm;\ - }\ - 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) +#define FILE "blind-norm.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -82,3 +52,37 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(struct stream *stream) +{ + size_t i, n; + TYPE x, y, z, a, norm;\ + do { + n = stream->ptr / stream->pixel_size; + 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]; + norm = sqrt(x * x + y * y + z * z + a * a); + if (!skip_x) + ((TYPE *)(stream->buf))[4 * i + 0] = norm; + if (!skip_y) + ((TYPE *)(stream->buf))[4 * i + 1] = norm; + if (!skip_z) + ((TYPE *)(stream->buf))[4 * i + 2] = norm; + if (!skip_a) + ((TYPE *)(stream->buf))[4 * i + 3] = norm; + } + 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); +} + +#endif diff --git a/src/blind-premultiply.c b/src/blind-premultiply.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-xyz]") @@ -7,33 +8,8 @@ static int skip_x = 0; static int skip_y = 0; static int skip_z = 0; -#define PROCESS(TYPE, SUFFIX)\ - static void\ - process_##SUFFIX(struct stream *stream)\ - {\ - size_t i, n;\ - TYPE a;\ - do {\ - n = stream->ptr / stream->pixel_size;\ - for (i = 0; i < n; i++) {\ - a = ((TYPE *)(stream->buf))[4 * i + 3];\ - if (!skip_x)\ - ((TYPE *)(stream->buf))[4 * i + 0] *= a;\ - if (!skip_y)\ - ((TYPE *)(stream->buf))[4 * i + 1] *= a;\ - if (!skip_z)\ - ((TYPE *)(stream->buf))[4 * i + 2] *= 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) +#define FILE "blind-premultiply.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -72,3 +48,31 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(struct stream *stream) +{ + size_t i, n; + TYPE a; + do { + n = stream->ptr / stream->pixel_size; + for (i = 0; i < n; i++) { + a = ((TYPE *)(stream->buf))[4 * i + 3]; + if (!skip_x) + ((TYPE *)(stream->buf))[4 * i + 0] *= a; + if (!skip_y) + ((TYPE *)(stream->buf))[4 * i + 1] *= a; + if (!skip_z) + ((TYPE *)(stream->buf))[4 * i + 2] *= 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); +} + +#endif diff --git a/src/blind-quaternion-product.c b/src/blind-quaternion-product.c @@ -1,32 +1,11 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("right-hand-stream") -#define PROCESS(TYPE, SUFFIX)\ - static void\ - process_##SUFFIX(struct stream *left, struct stream *right, size_t n)\ - {\ - size_t i;\ - TYPE *lx, *ly, *lz, *la, *rx, *ry, *rz, *ra, x, y, z, a;\ - for (i = 0; i < n; i += 4 * sizeof(TYPE)) {\ - lx = ((TYPE *)(left->buf + i)) + 0, rx = ((TYPE *)(right->buf + i)) + 0;\ - ly = ((TYPE *)(left->buf + i)) + 1, ry = ((TYPE *)(right->buf + i)) + 1;\ - lz = ((TYPE *)(left->buf + i)) + 2, rz = ((TYPE *)(right->buf + i)) + 2;\ - la = ((TYPE *)(left->buf + i)) + 3, ra = ((TYPE *)(right->buf + i)) + 3;\ - x = *lx * *rx - *ly * *ry - *lz * *rz - *la * *ra;\ - y = *lz * *ra - *la * *rz + *lx * *ry + *ly * *rx;\ - z = *la * *ry - *ly * *rz + *lx * *rz + *lz * *rx;\ - a = *ly * *rz - *lz * *rz + *lx * *ra + *la * *rx;\ - *lx = x;\ - *ly = y;\ - *lz = z;\ - *la = a;\ - }\ - } - -PROCESS(double, lf) -PROCESS(float, f) +#define FILE "blind-quaternion-product.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -51,3 +30,28 @@ main(int argc, char *argv[]) process_two_streams(&left, &right, STDOUT_FILENO, "<stdout>", process); return 0; } + +#else + +static void +PROCESS(struct stream *left, struct stream *right, size_t n) +{ + size_t i; + TYPE *lx, *ly, *lz, *la, *rx, *ry, *rz, *ra, x, y, z, a; + for (i = 0; i < n; i += 4 * sizeof(TYPE)) { + lx = ((TYPE *)(left->buf + i)) + 0, rx = ((TYPE *)(right->buf + i)) + 0; + ly = ((TYPE *)(left->buf + i)) + 1, ry = ((TYPE *)(right->buf + i)) + 1; + lz = ((TYPE *)(left->buf + i)) + 2, rz = ((TYPE *)(right->buf + i)) + 2; + la = ((TYPE *)(left->buf + i)) + 3, ra = ((TYPE *)(right->buf + i)) + 3; + x = *lx * *rx - *ly * *ry - *lz * *rz - *la * *ra; + y = *lz * *ra - *la * *rz + *lx * *ry + *ly * *rx; + z = *la * *ry - *ly * *rz + *lx * *rz + *lz * *rx; + a = *ly * *rz - *lz * *rz + *lx * *ra + *la * *rx; + *lx = x; + *ly = y; + *lz = z; + *la = a; + } +} + +#endif diff --git a/src/blind-radial-gradient.c b/src/blind-radial-gradient.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("-w width -h height") @@ -7,79 +8,8 @@ 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 = 0.5;\ - 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 - stream->ptr)) {\ - ewriteall(STDOUT_FILENO, buf, ptr * sizeof(*buf), "<stdout>");\ - 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] = buf[ptr][2] = buf[ptr][3] = x;\ - if (++ptr == ELEMENTSOF(buf)) {\ - ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>");\ - 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) / rd;\ - p = pow(abs(p / norm), pe);\ - r = pow(abs(r / norm), re);\ - x = pow(p + r, e);\ - buf[ptr][0] = buf[ptr][1] = buf[ptr][2] = buf[ptr][3] = x;\ - if (++ptr == ELEMENTSOF(buf)) {\ - ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>");\ - ptr = 0;\ - }\ - }\ - }\ - }\ - }\ - } - -PROCESS(double, lf) -PROCESS(float, f) +#define FILE "blind-radial-gradient.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -124,3 +54,77 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(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 = 0.5; + 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 - stream->ptr)) { + ewriteall(STDOUT_FILENO, buf, ptr * sizeof(*buf), "<stdout>"); + 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] = buf[ptr][2] = buf[ptr][3] = x; + if (++ptr == ELEMENTSOF(buf)) { + ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>"); + 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) / rd; + p = pow(abs(p / norm), pe); + r = pow(abs(r / norm), re); + x = pow(p + r, e); + buf[ptr][0] = buf[ptr][1] = buf[ptr][2] = buf[ptr][3] = x; + if (++ptr == ELEMENTSOF(buf)) { + ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>"); + ptr = 0; + } + } + } + } + } +} + +#endif diff --git a/src/blind-round-wave.c b/src/blind-round-wave.c @@ -1,45 +1,13 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-e]") static int equal = 0; -#define PROCESS(TYPE, SUFFIX)\ - static void\ - process_##SUFFIX(struct stream *stream)\ - {\ - size_t i, j, n;\ - TYPE v, *p;\ - do {\ - if (equal) {\ - n = stream->ptr / stream->pixel_size;\ - for (i = 0; i < n; i++) {\ - p = (TYPE *)(stream->buf) + i * stream->n_chan;\ - v = posmod(*p + 1, (TYPE)4) - 1;\ - v = v < 1 ? 1 - v * v / 2 : (v - 2) * (v - 2) / 2;\ - for (j = 0; j < stream->n_chan; j++)\ - p[j] = v;\ - }\ - n *= stream->pixel_size;\ - } else {\ - n = stream->ptr / stream->chan_size;\ - for (i = 0; i < n; i++) {\ - p = (TYPE *)(stream->buf) + i;\ - v = posmod(*p + 1, (TYPE)4) - 1;\ - *p = v < 1 ? 1 - v * v / 2 : (v - 2) * (v - 2) / 2;\ - }\ - n *= stream->chan_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) +#define FILE "blind-round-wave.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -72,3 +40,39 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(struct stream *stream) +{ + size_t i, j, n; + TYPE v, *p; + do { + if (equal) { + n = stream->ptr / stream->pixel_size; + for (i = 0; i < n; i++) { + p = (TYPE *)(stream->buf) + i * stream->n_chan; + v = posmod(*p + 1, (TYPE)4) - 1; + v = v < 1 ? 1 - v * v / 2 : (v - 2) * (v - 2) / 2; + for (j = 0; j < stream->n_chan; j++) + p[j] = v; + } + n *= stream->pixel_size; + } else { + n = stream->ptr / stream->chan_size; + for (i = 0; i < n; i++) { + p = (TYPE *)(stream->buf) + i; + v = posmod(*p + 1, (TYPE)4) - 1; + *p = v < 1 ? 1 - v * v / 2 : (v - 2) * (v - 2) / 2; + } + n *= stream->chan_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); +} + +#endif diff --git a/src/blind-sawtooth-wave.c b/src/blind-sawtooth-wave.c @@ -1,43 +1,13 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-e]") static int equal = 0; -#define PROCESS(TYPE, SUFFIX)\ - static void\ - process_##SUFFIX(struct stream *stream)\ - {\ - size_t i, j, n;\ - TYPE v, *p;\ - do {\ - if (equal) {\ - n = stream->ptr / stream->pixel_size;\ - for (i = 0; i < n; i++) {\ - p = (TYPE *)(stream->buf) + i * stream->n_chan;\ - v = posmod(*p, (TYPE)1);\ - for (j = 0; j < stream->n_chan; j++)\ - p[j] = v;\ - }\ - n *= stream->pixel_size;\ - } else {\ - n = stream->ptr / stream->chan_size;\ - for (i = 0; i < n; i++) {\ - p = (TYPE *)(stream->buf) + i;\ - *p = posmod(*p, (TYPE)1);\ - }\ - n *= stream->chan_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) +#define FILE "blind-sawtooth-wave.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -70,3 +40,37 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(struct stream *stream) +{ + size_t i, j, n; + TYPE v, *p; + do { + if (equal) { + n = stream->ptr / stream->pixel_size; + for (i = 0; i < n; i++) { + p = (TYPE *)(stream->buf) + i * stream->n_chan; + v = posmod(*p, (TYPE)1); + for (j = 0; j < stream->n_chan; j++) + p[j] = v; + } + n *= stream->pixel_size; + } else { + n = stream->ptr / stream->chan_size; + for (i = 0; i < n; i++) { + p = (TYPE *)(stream->buf) + i; + *p = posmod(*p, (TYPE)1); + } + n *= stream->chan_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); +} + +#endif diff --git a/src/blind-set-luma.c b/src/blind-set-luma.c @@ -1,86 +1,11 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("luma-stream") -#define PROCESS(TYPE)\ - do {\ - size_t i;\ - TYPE a, y;\ - for (i = 0; i < n; i += colour->pixel_size) {\ - a = ((TYPE *)(luma->buf + i))[1];\ - a *= ((TYPE *)(luma->buf + i))[3];\ - y = ((TYPE *)(colour->buf + i))[1];\ - ((TYPE *)(colour->buf + i))[0] += y * a - y;\ - ((TYPE *)(colour->buf + i))[1] = y * a;\ - ((TYPE *)(colour->buf + i))[2] += y * a - y;\ - /* - * Note, this changes the luma only, not the saturation, - * so the result may look a bit weird. To change both - * you can use `blind-arithm mul`. - * - * Explaination of algorithm: - * - * Y is the luma, but (X, Z) is not the chroma, - * but in CIELAB, L* is the luma and (a*, *b) is - * the chroma. Multiplying - * - * ⎛0 1 0⎞ - * ⎜1 −1 0⎟ - * ⎝0 1 −1⎠ - * - * (X Y Z)' gives a colour model similar to - * CIE L*a*b*: a model where each parameter is - * a linear transformation of the corresponding - * parameter in CIE L*a*b*. The inverse of that - * matrix is - * - * ⎛1 1 0⎞ - * ⎜1 0 0⎟ - * ⎝0 0 −1⎠ - * - * and - * - * ⎛1 1 0⎞⎛a 0 0⎞⎛0 1 0⎞ ⎛1 a−1 0⎞ - * ⎜1 0 0⎟⎜0 1 0⎟⎜1 −1 0⎟ = ⎜0 a 0⎟. - * ⎝0 0 −1⎠⎝0 0 1⎠⎝0 1 −1⎠ ⎝0 a−1 1⎠ - * - * Explanation of why changing only the luma looks weird: - * - * Consider when you are workings with colours, - * when you want to change the brightness of a - * colour, you multiply all parameters: red, green, - * and blue, with the same value (this is however - * only an approximation in most cases, since you - * are usually usally working with colours that - * have the sRGB transfer function applied to their - * parameters). This action is the same in all - * colour models and colour spaces that are a - * linear transformation of the sRGB colour spaces - * (sans transfer function); this is simply because - * of the properties of linear transformations. - * - * The reason you change brightness this way can - * be explained by how objects reflect colour. - * Objects can only reject colours that are present - * in the light source. A ideal white object will look - * pure red if the light sources is ideal red, and a - * a ideal blue object will pure black in the same - * light source. An object can also not reflect - * colours brighter than the source. When the brightness - * of a light source is changed, the intensity of all - * colours (by wavelength) it emits is multiplied by - * one value. Therefore, when changing the brightness - * it looks most natural when all primaries (red, green, - * and blue) are multiplied by one value, or all - * parameters of the used colour spaces is a linear - * transformation of sRGB, such as CIE XYZ. - */\ - }\ - } while (0) - -static void process_xyza (struct stream *colour, struct stream *luma, size_t n) {PROCESS(double);} -static void process_xyzaf(struct stream *colour, struct stream *luma, size_t n) {PROCESS(float);} +#define FILE "blind-set-luma.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -94,9 +19,9 @@ main(int argc, char *argv[]) eopen_stream(&luma, argv[0]); if (!strcmp(colour.pixfmt, "xyza")) - process = process_xyza; + process = process_lf; else if (!strcmp(colour.pixfmt, "xyza f")) - process = process_xyzaf; + process = process_f; else eprintf("pixel format %s is not supported, try xyza\n", colour.pixfmt); @@ -105,3 +30,84 @@ main(int argc, char *argv[]) process_two_streams(&colour, &luma, STDOUT_FILENO, "<stdout>", process); return 0; } + +#else + +static void +PROCESS(struct stream *colour, struct stream *luma, size_t n) +{\ + size_t i; + TYPE a, y; + for (i = 0; i < n; i += colour->pixel_size) { + a = ((TYPE *)(luma->buf + i))[1]; + a *= ((TYPE *)(luma->buf + i))[3]; + y = ((TYPE *)(colour->buf + i))[1]; + ((TYPE *)(colour->buf + i))[0] += y * a - y; + ((TYPE *)(colour->buf + i))[1] = y * a; + ((TYPE *)(colour->buf + i))[2] += y * a - y; + /* + * Note, this changes the luma only, not the saturation, + * so the result may look a bit weird. To change both + * you can use `blind-arithm mul`. + * + * Explaination of algorithm: + * + * Y is the luma, but (X, Z) is not the chroma, + * but in CIELAB, L* is the luma and (a*, *b) is + * the chroma. Multiplying + * + * ⎛0 1 0⎞ + * ⎜1 −1 0⎟ + * ⎝0 1 −1⎠ + * + * (X Y Z)' gives a colour model similar to + * CIE L*a*b*: a model where each parameter is + * a linear transformation of the corresponding + * parameter in CIE L*a*b*. The inverse of that + * matrix is + * + * ⎛1 1 0⎞ + * ⎜1 0 0⎟ + * ⎝0 0 −1⎠ + * + * and + * + * ⎛1 1 0⎞⎛a 0 0⎞⎛0 1 0⎞ ⎛1 a−1 0⎞ + * ⎜1 0 0⎟⎜0 1 0⎟⎜1 −1 0⎟ = ⎜0 a 0⎟. + * ⎝0 0 −1⎠⎝0 0 1⎠⎝0 1 −1⎠ ⎝0 a−1 1⎠ + * + * Explanation of why changing only the luma looks weird: + * + * Consider when you are workings with colours, + * when you want to change the brightness of a + * colour, you multiply all parameters: red, green, + * and blue, with the same value (this is however + * only an approximation in most cases, since you + * are usually usally working with colours that + * have the sRGB transfer function applied to their + * parameters). This action is the same in all + * colour models and colour spaces that are a + * linear transformation of the sRGB colour spaces + * (sans transfer function); this is simply because + * of the properties of linear transformations. + * + * The reason you change brightness this way can + * be explained by how objects reflect colour. + * Objects can only reject colours that are present + * in the light source. A ideal white object will look + * pure red if the light sources is ideal red, and a + * a ideal blue object will pure black in the same + * light source. An object can also not reflect + * colours brighter than the source. When the brightness + * of a light source is changed, the intensity of all + * colours (by wavelength) it emits is multiplied by + * one value. Therefore, when changing the brightness + * it looks most natural when all primaries (red, green, + * and blue) are multiplied by one value, or all + * parameters of the used colour spaces is a linear + * transformation of sRGB, such as CIE XYZ. + */ + } +} + +#endif diff --git a/src/blind-sinc-wave.c b/src/blind-sinc-wave.c @@ -1,73 +1,13 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #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;\ - do {\ - if (!m) {\ - m = grad->frame_size;\ - if (theta0) {\ - while (theta0->ptr < theta0->frame_size)\ - if (!eread_stream(theta0, theta0->frame_size - theta0->ptr))\ - return;\ - theta0xyza = (TYPE *)theta0->buf;\ - theta0x = (theta0xyza)[0];\ - theta0y = (theta0xyza)[1];\ - theta0z = (theta0xyza)[2];\ - theta0a = (theta0xyza)[3];\ - memmove(theta0->buf, theta0->buf + theta0->frame_size,\ - theta0->ptr -= theta0->frame_size);\ - }\ - }\ - 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 + theta0y)) / 2 + (TYPE)0.5;\ - ((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 + theta0x)) / 2 + (TYPE)0.5;\ - y = (y ? sin(y + theta0y) / y : sin(y + theta0y)) / 2 + (TYPE)0.5;\ - z = (z ? sin(z + theta0z) / z : sin(z + theta0z)) / 2 + (TYPE)0.5;\ - a = (a ? sin(a + theta0a) / a : sin(a + theta0a)) / 2 + (TYPE)0.5;\ - ((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) +#define FILE "blind-sinc-wave.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -111,3 +51,67 @@ main(int argc, char *argv[]) process(&stream, have_theta0 ? &theta0 : NULL); return 0; } + +#else + +static void +PROCESS(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; + do { + if (!m) { + m = grad->frame_size; + if (theta0) { + while (theta0->ptr < theta0->frame_size) + if (!eread_stream(theta0, theta0->frame_size - theta0->ptr)) + return; + theta0xyza = (TYPE *)theta0->buf; + theta0x = (theta0xyza)[0]; + theta0y = (theta0xyza)[1]; + theta0z = (theta0xyza)[2]; + theta0a = (theta0xyza)[3]; + memmove(theta0->buf, theta0->buf + theta0->frame_size, + theta0->ptr -= theta0->frame_size); + } + } + 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 + theta0y)) / 2 + (TYPE)0.5; + ((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 + theta0x)) / 2 + (TYPE)0.5; + y = (y ? sin(y + theta0y) / y : sin(y + theta0y)) / 2 + (TYPE)0.5; + z = (z ? sin(z + theta0z) / z : sin(z + theta0z)) / 2 + (TYPE)0.5; + a = (a ? sin(a + theta0a) / a : sin(a + theta0a)) / 2 + (TYPE)0.5; + ((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); +} + +#endif diff --git a/src/blind-sine-wave.c b/src/blind-sine-wave.c @@ -1,47 +1,13 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-e]") static int equal = 0; -#define PROCESS(TYPE, SUFFIX)\ - static void\ - process_##SUFFIX(struct stream *stream)\ - {\ - size_t i, j, n;\ - TYPE v, *p;\ - do {\ - if (equal) {\ - n = stream->ptr / stream->pixel_size;\ - for (i = 0; i < n; i++) {\ - p = (TYPE *)(stream->buf) + i * stream->n_chan;\ - v = posmod(*p, (TYPE)2);\ - v = v > 1 ? 2 - v : v;\ - v = 1 - (cos(v * (TYPE)M_PI) + 1) / 2;\ - for (j = 0; j < stream->n_chan; j++)\ - p[j] = v;\ - }\ - n *= stream->pixel_size;\ - } else {\ - n = stream->ptr / stream->chan_size;\ - for (i = 0; i < n; i++) {\ - p = (TYPE *)(stream->buf) + i;\ - v = posmod(*p, (TYPE)2);\ - v = v > 1 ? 2 - v : v;\ - *p = 1 - (cos(v * (TYPE)M_PI) + 1) / 2;\ - }\ - n *= stream->chan_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) +#define FILE "blind-sine-wave.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -74,3 +40,41 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(struct stream *stream) +{ + size_t i, j, n; + TYPE v, *p; + do { + if (equal) { + n = stream->ptr / stream->pixel_size; + for (i = 0; i < n; i++) { + p = (TYPE *)(stream->buf) + i * stream->n_chan; + v = posmod(*p, (TYPE)2); + v = v > 1 ? 2 - v : v; + v = 1 - (cos(v * (TYPE)M_PI) + 1) / 2; + for (j = 0; j < stream->n_chan; j++) + p[j] = v; + } + n *= stream->pixel_size; + } else { + n = stream->ptr / stream->chan_size; + for (i = 0; i < n; i++) { + p = (TYPE *)(stream->buf) + i; + v = posmod(*p, (TYPE)2); + v = v > 1 ? 2 - v : v; + *p = 1 - (cos(v * (TYPE)M_PI) + 1) / 2; + } + n *= stream->chan_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); +} + +#endif diff --git a/src/blind-single-colour.c b/src/blind-single-colour.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-f frames | -f 'inf'] [-F pixel-format] -w width -h height (X Y Z | Y) [alpha]") @@ -7,29 +8,8 @@ static struct stream stream = { .width = 0, .height = 0, .frames = 1 }; static double X, Y, Z, alpha = 1; static int inf = 0; -#define PROCESS(TYPE)\ - do {\ - typedef TYPE pixel_t[4];\ - pixel_t buf[BUFSIZ / 4];\ - size_t x, y, n;\ - ssize_t r;\ - \ - for (x = 0; x < ELEMENTSOF(buf); x++) {\ - buf[x][0] = (TYPE)X;\ - buf[x][1] = (TYPE)Y;\ - buf[x][2] = (TYPE)Z;\ - buf[x][3] = (TYPE)alpha;\ - }\ - while (inf || stream.frames--)\ - for (y = stream.height; y--;)\ - for (x = stream.width * sizeof(*buf); x;)\ - for (x -= n = MIN(sizeof(buf), x); n; n -= (size_t)r)\ - if ((r = write(STDOUT_FILENO, buf, n)) < 0)\ - eprintf("write <stdout>:");\ - } while (0) - -static void process_xyza(void) {PROCESS(double);} -static void process_xyzaf(void) {PROCESS(float);} +#define FILE "blind-single-colour.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -79,9 +59,9 @@ main(int argc, char *argv[]) pixfmt = get_pixel_format(pixfmt, "xyza"); if (!strcmp(pixfmt, "xyza")) - process = process_xyza; + process = process_lf; else if (!strcmp(pixfmt, "xyza f")) - process = process_xyzaf; + process = process_f; else eprintf("pixel format %s is not supported, try xyza\n", pixfmt); @@ -92,3 +72,28 @@ main(int argc, char *argv[]) process(); return 0; } + +#else + +static void +PROCESS(void) +{ + typedef TYPE pixel_t[4]; + pixel_t buf[BUFSIZ / 4]; + size_t x, y, n; + ssize_t r; + for (x = 0; x < ELEMENTSOF(buf); x++) { + buf[x][0] = (TYPE)X; + buf[x][1] = (TYPE)Y; + buf[x][2] = (TYPE)Z; + buf[x][3] = (TYPE)alpha; + } + while (inf || stream.frames--) + for (y = stream.height; y--;) + for (x = stream.width * sizeof(*buf); x;) + for (x -= n = MIN(sizeof(buf), x); n; n -= (size_t)r) + if ((r = write(STDOUT_FILENO, buf, n)) < 0) + eprintf("write <stdout>:"); +} + +#endif diff --git a/src/blind-spectrum.c b/src/blind-spectrum.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-y] [-z depth] spectrum-stream") @@ -6,121 +7,8 @@ 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) +#define FILE "blind-spectrum.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -162,3 +50,119 @@ main(int argc, char *argv[]) process(&stream, &spectrum); return 0; } + +#else + +static void +PROCESS(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); +} + +#endif diff --git a/src/blind-spiral-gradient.c b/src/blind-spiral-gradient.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-s spirals | t] [-al] -w width -h height") @@ -12,108 +13,8 @@ static size_t height = 0; static int with_params; static int with_vector; -#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;\ - TYPE x3 = 1, y3 = 0, rd = 1, P, R, Rx, Ry, Pe = 2, Re = 2, PRe = 0.5;\ - size_t ix, iy, ptr = 0;\ - for (;;) {\ - while (stream->ptr < stream->frame_size) {\ - if (!eread_stream(stream, stream->frame_size - stream->ptr)) {\ - ewriteall(STDOUT_FILENO, buf, ptr * sizeof(*buf), "<stdout>");\ - return;\ - }\ - }\ - params = (TYPE *)stream->buf;\ - x1 = (params)[0];\ - y1 = (params)[1];\ - x2 = (params)[4];\ - y2 = (params)[5];\ - if (with_vector) {\ - x3 = (params)[8];\ - y3 = (params)[9];\ - Pe = (params)[12];\ - Re = (params)[13];\ - rd = (params)[14];\ - PRe = 1 / sqrt(Pe * Re);\ - b = sqrt(x3 * x3 + y3 * y3);\ - x3 /= b;\ - y3 /= b;\ - }\ - if (with_params) {\ - a = (params)[with_vector ? 16 : 8];\ - e = (params)[with_vector ? 17 : 9];\ - p = (params)[with_vector ? 18 : 10];\ - k = (params)[with_vector ? 19 : 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);\ - b *= (TYPE)spirals;\ - 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;\ - if (!x && !y) {\ - v = 0;\ - } else {\ - v = atan2(y, x);\ - if (anticlockwise)\ - v = -v;\ - v -= u;\ - v += 4 * (TYPE)M_PI;\ - v = mod(v, 2 * (TYPE)M_PI);\ - }\ - if (!with_vector) {\ - r = sqrt(x * x + y * y);\ - } else {\ - P = x * x3 + y * y3;\ - Rx = x - P * x3;\ - Ry = y - P * y3;\ - R = sqrt(Rx * Rx + Ry * Ry) / rd;\ - P = pow(abs(P), Pe);\ - R = pow(abs(R), Re);\ - r = pow(P + R, PRe);\ - }\ - 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);\ - }\ - if (angle)\ - r = (TYPE)(int)(r + 1) + v / (2 * (TYPE)M_PI); \ - else\ - r = mod(r, 1 / (TYPE)spirals) * (TYPE)spirals + r - mod(r, (TYPE)1);\ - buf[ptr][0] = buf[ptr][1] = buf[ptr][2] = buf[ptr][3] = r;\ - if (++ptr == ELEMENTSOF(buf)) {\ - ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>");\ - ptr = 0;\ - }\ - }\ - }\ - }\ - } - -PROCESS(double, lf) -PROCESS(float, f) +#define FILE "blind-spiral-gradient.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -173,3 +74,106 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(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; + TYPE x3 = 1, y3 = 0, rd = 1, P, R, Rx, Ry, Pe = 2, Re = 2, PRe = 0.5; + size_t ix, iy, ptr = 0; + for (;;) { + while (stream->ptr < stream->frame_size) { + if (!eread_stream(stream, stream->frame_size - stream->ptr)) { + ewriteall(STDOUT_FILENO, buf, ptr * sizeof(*buf), "<stdout>"); + return; + } + } + params = (TYPE *)stream->buf; + x1 = (params)[0]; + y1 = (params)[1]; + x2 = (params)[4]; + y2 = (params)[5]; + if (with_vector) { + x3 = (params)[8]; + y3 = (params)[9]; + Pe = (params)[12]; + Re = (params)[13]; + rd = (params)[14]; + PRe = 1 / sqrt(Pe * Re); + b = sqrt(x3 * x3 + y3 * y3); + x3 /= b; + y3 /= b; + } + if (with_params) { + a = (params)[with_vector ? 16 : 8]; + e = (params)[with_vector ? 17 : 9]; + p = (params)[with_vector ? 18 : 10]; + k = (params)[with_vector ? 19 : 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); + b *= (TYPE)spirals; + 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; + if (!x && !y) { + v = 0; + } else { + v = atan2(y, x); + if (anticlockwise) + v = -v; + v -= u; + v += 4 * (TYPE)M_PI; + v = mod(v, 2 * (TYPE)M_PI); + } + if (!with_vector) { + r = sqrt(x * x + y * y); + } else { + P = x * x3 + y * y3; + Rx = x - P * x3; + Ry = y - P * y3; + R = sqrt(Rx * Rx + Ry * Ry) / rd; + P = pow(abs(P), Pe); + R = pow(abs(R), Re); + r = pow(P + R, PRe); + } + 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); + } + if (angle) + r = (TYPE)(int)(r + 1) + v / (2 * (TYPE)M_PI); + else + r = mod(r, 1 / (TYPE)spirals) * (TYPE)spirals + r - mod(r, (TYPE)1); + buf[ptr][0] = buf[ptr][1] = buf[ptr][2] = buf[ptr][3] = r; + if (++ptr == ELEMENTSOF(buf)) { + ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>"); + ptr = 0; + } + } + } + } +} + +#endif diff --git a/src/blind-square-gradient.c b/src/blind-square-gradient.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("-w width -h height") @@ -7,60 +8,8 @@ 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 - stream->ptr)) {\ - ewriteall(STDOUT_FILENO, buf, ptr * sizeof(*buf), "<stdout>");\ - 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] = buf[ptr][3] = x;\ - if (++ptr == ELEMENTSOF(buf)) {\ - ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>");\ - ptr = 0;\ - }\ - }\ - }\ - }\ - } - -PROCESS(double, lf) -PROCESS(float, f) +#define FILE "blind-square-gradient.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -105,3 +54,58 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(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 - stream->ptr)) { + ewriteall(STDOUT_FILENO, buf, ptr * sizeof(*buf), "<stdout>"); + 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] = buf[ptr][3] = x; + if (++ptr == ELEMENTSOF(buf)) { + ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>"); + ptr = 0; + } + } + } + } +} + +#endif diff --git a/src/blind-tee.c b/src/blind-tee.c @@ -3,10 +3,6 @@ USAGE("[file ...]") -#if !defined(PIPE_BUF) -# define PIPE_BUF BUFSIZ -#endif - int main(int argc, char *argv[]) { diff --git a/src/blind-time-blur.c b/src/blind-time-blur.c @@ -1,52 +1,13 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("alpha-stream") static int first = 1; -#define PROCESS(TYPE)\ - do {\ - typedef TYPE pixel_t[4];\ - pixel_t *restrict clr = (pixel_t *)cbuf;\ - pixel_t *restrict alf = (pixel_t *)abuf;\ - pixel_t *img = (pixel_t *)output;\ - size_t i, n = colour->frame_size / sizeof(pixel_t);\ - TYPE a1, a2;\ - \ - if (first) {\ - memcpy(output, cbuf, colour->frame_size);\ - first = 0;\ - return;\ - }\ - \ - for (i = 0; i < n; i++, clr++, alf++, img++) {\ - a1 = (*img)[3];\ - a2 = (*clr)[3] * (*alf)[1] * (*alf)[3];\ - a1 *= (1 - a2);\ - (*img)[0] = (*img)[0] * a1 + (*clr)[0] * a2;\ - (*img)[1] = (*img)[1] * a1 + (*clr)[1] * a2;\ - (*img)[2] = (*img)[2] * a1 + (*clr)[2] * a2;\ - (*img)[3] = a1 + a2;\ - }\ - \ - (void) colour;\ - (void) alpha;\ - } while (0) - -static void -process_lf(char *output, char *restrict cbuf, char *restrict abuf, - struct stream *colour, struct stream *alpha) -{ - PROCESS(double); -} - -static void -process_f(char *output, char *restrict cbuf, char *restrict abuf, - struct stream *colour, struct stream *alpha) -{ - PROCESS(float); -} +#define FILE "blind-time-blur.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -79,3 +40,39 @@ main(int argc, char *argv[]) process_each_frame_two_streams(&colour, &alpha, STDOUT_FILENO, "<stdout>", process); return 0; } + +#else + +static void +PROCESS(char *output, char *restrict cbuf, char *restrict abuf, + struct stream *colour, struct stream *alpha) +{ + typedef TYPE pixel_t[4]; + pixel_t *restrict clr = (pixel_t *)cbuf; + pixel_t *restrict alf = (pixel_t *)abuf; + pixel_t *img = (pixel_t *)output; + size_t i, n = colour->frame_size / sizeof(pixel_t); + TYPE a1, a2; + + if (first) { + memcpy(output, cbuf, colour->frame_size); + first = 0; + return; + } + + for (i = 0; i < n; i++, clr++, alf++, img++) { + a1 = (*img)[3]; + a2 = (*clr)[3] * (*alf)[1] * (*alf)[3]; + a1 *= (1 - a2); + (*img)[0] = (*img)[0] * a1 + (*clr)[0] * a2; + (*img)[1] = (*img)[1] * a1 + (*clr)[1] * a2; + (*img)[2] = (*img)[2] * a1 + (*clr)[2] * a2; + (*img)[3] = a1 + a2; + } + + (void) colour; + (void) alpha; + +} + +#endif diff --git a/src/blind-to-text.c b/src/blind-to-text.c @@ -1,8 +1,6 @@ /* See LICENSE file for copyright and license details. */ #include "common.h" -#include <string.h> - USAGE("") #define PROCESS(TYPE, CAST, FMT)\ diff --git a/src/blind-to-video.c b/src/blind-to-video.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-d] frame-rate ffmpeg-arguments ...") @@ -6,55 +7,8 @@ USAGE("[-d] frame-rate ffmpeg-arguments ...") static int draft = 0; static int fd; -#define PROCESS(TYPE)\ - do {\ - char *buf = stream->buf;\ - TYPE *pixel, r, g, b;\ - uint16_t *pixels, *end;\ - uint16_t pixbuf[BUFSIZ / sizeof(uint16_t)];\ - long int a, y, u, v;\ - size_t ptr;\ - pixels = pixbuf;\ - end = pixbuf + ELEMENTSOF(pixbuf);\ - if (draft) {\ - for (ptr = 0; ptr < n; ptr += 4 * sizeof(TYPE)) {\ - pixel = (TYPE *)(buf + ptr);\ - ciexyz_to_scaled_yuv(pixel[0], pixel[1], pixel[2], &r, &g, &b);\ - y = (long int)r + 16L * 256L;\ - u = (long int)g + 128L * 256L;\ - v = (long int)b + 128L * 256L;\ - *pixels++ = 0xFFFFU;\ - *pixels++ = htole((uint16_t)CLIP(0, y, 0xFFFFL));\ - *pixels++ = htole((uint16_t)CLIP(0, u, 0xFFFFL));\ - *pixels++ = htole((uint16_t)CLIP(0, v, 0xFFFFL));\ - if (pixels == end)\ - ewriteall(fd, pixels = pixbuf, sizeof(pixbuf), "<subprocess>");\ - }\ - } else {\ - for (ptr = 0; ptr < n; ptr += 4 * sizeof(TYPE)) {\ - pixel = (TYPE *)(buf + ptr);\ - a = (long int)(pixel[3] * 0xFFFFL);\ - ciexyz_to_srgb(pixel[0], pixel[1], pixel[2], &r, &g, &b);\ - r = srgb_encode(r);\ - g = srgb_encode(g);\ - b = srgb_encode(b);\ - srgb_to_yuv(r, g, b, pixel + 0, pixel + 1, pixel + 2);\ - y = (long int)(pixel[0] * 0xFFFFL) + 16L * 256L;\ - u = (long int)(pixel[1] * 0xFFFFL) + 128L * 256L;\ - v = (long int)(pixel[2] * 0xFFFFL) + 128L * 256L;\ - *pixels++ = htole((uint16_t)CLIP(0, a, 0xFFFFL));\ - *pixels++ = htole((uint16_t)CLIP(0, y, 0xFFFFL));\ - *pixels++ = htole((uint16_t)CLIP(0, u, 0xFFFFL));\ - *pixels++ = htole((uint16_t)CLIP(0, v, 0xFFFFL));\ - if (pixels == end)\ - ewriteall(fd, pixels = pixbuf, sizeof(pixbuf), "<subprocess>");\ - }\ - }\ - ewriteall(fd, pixbuf, (size_t)(pixels - pixbuf) * sizeof(*pixels), "<subprocess>");\ - } while (0) - -static void process_xyza (struct stream *stream, size_t n) {PROCESS(double);} -static void process_xyzaf(struct stream *stream, size_t n) {PROCESS(float);} +#define FILE "blind-to-video.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -94,9 +48,9 @@ main(int argc, char *argv[]) sprintf(geometry, "%zux%zu", stream.width, stream.height); if (!strcmp(stream.pixfmt, "xyza")) - process = process_xyza; + process = process_lf; else if (!strcmp(stream.pixfmt, "xyza f")) - process = process_xyzaf; + process = process_f; else eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt); @@ -121,3 +75,55 @@ main(int argc, char *argv[]) ewaitpid(pid, &status, 0); return !!status; } + +#else + +static void +PROCESS(struct stream *stream, size_t n) +{ + char *buf = stream->buf; + TYPE *pixel, r, g, b; + uint16_t *pixels, *end; + uint16_t pixbuf[BUFSIZ / sizeof(uint16_t)]; + long int a, y, u, v; + size_t ptr; + pixels = pixbuf; + end = pixbuf + ELEMENTSOF(pixbuf); + if (draft) { + for (ptr = 0; ptr < n; ptr += 4 * sizeof(TYPE)) { + pixel = (TYPE *)(buf + ptr); + ciexyz_to_scaled_yuv(pixel[0], pixel[1], pixel[2], &r, &g, &b); + y = (long int)r + 16L * 256L; + u = (long int)g + 128L * 256L; + v = (long int)b + 128L * 256L; + *pixels++ = 0xFFFFU; + *pixels++ = htole((uint16_t)CLIP(0, y, 0xFFFFL)); + *pixels++ = htole((uint16_t)CLIP(0, u, 0xFFFFL)); + *pixels++ = htole((uint16_t)CLIP(0, v, 0xFFFFL)); + if (pixels == end) + ewriteall(fd, pixels = pixbuf, sizeof(pixbuf), "<subprocess>"); + } + } else { + for (ptr = 0; ptr < n; ptr += 4 * sizeof(TYPE)) { + pixel = (TYPE *)(buf + ptr); + a = (long int)(pixel[3] * 0xFFFFL); + ciexyz_to_srgb(pixel[0], pixel[1], pixel[2], &r, &g, &b); + r = srgb_encode(r); + g = srgb_encode(g); + b = srgb_encode(b); + srgb_to_yuv(r, g, b, pixel + 0, pixel + 1, pixel + 2); + y = (long int)(pixel[0] * 0xFFFFL) + 16L * 256L; + u = (long int)(pixel[1] * 0xFFFFL) + 128L * 256L; + v = (long int)(pixel[2] * 0xFFFFL) + 128L * 256L; + *pixels++ = htole((uint16_t)CLIP(0, a, 0xFFFFL)); + *pixels++ = htole((uint16_t)CLIP(0, y, 0xFFFFL)); + *pixels++ = htole((uint16_t)CLIP(0, u, 0xFFFFL)); + *pixels++ = htole((uint16_t)CLIP(0, v, 0xFFFFL)); + if (pixels == end) + ewriteall(fd, pixels = pixbuf, sizeof(pixbuf), "<subprocess>"); + } + } + ewriteall(fd, pixbuf, (size_t)(pixels - pixbuf) * sizeof(*pixels), "<subprocess>"); +} + +#endif diff --git a/src/blind-triangular-wave.c b/src/blind-triangular-wave.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-es]") @@ -6,46 +7,8 @@ USAGE("[-es]") static int equal = 0; static int spiral = 0; -#define PROCESS(TYPE, SUFFIX)\ - static void\ - process_##SUFFIX(struct stream *stream)\ - {\ - size_t i, j, n;\ - TYPE v, *p;\ - do {\ - if (equal) {\ - n = stream->ptr / stream->pixel_size;\ - for (i = 0; i < n; i++) {\ - p = (TYPE *)(stream->buf) + i * stream->n_chan;\ - v = posmod(*p, (TYPE)2);\ - v = v > 1 ? 2 - v : v;\ - if (spiral)\ - v = (v > (TYPE)0.5 ? 1 - v : v) * 2;\ - for (j = 0; j < stream->n_chan; j++)\ - p[j] = v;\ - }\ - n *= stream->pixel_size;\ - } else {\ - n = stream->ptr / stream->chan_size;\ - for (i = 0; i < n; i++) {\ - p = (TYPE *)(stream->buf) + i;\ - v = posmod(*p, (TYPE)2);\ - v = v > 1 ? 2 - v : v;\ - if (spiral)\ - v = (v > (TYPE)0.5 ? 1 - v : v) * 2;\ - *p = v;\ - }\ - n *= stream->chan_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) +#define FILE "blind-triangular-wave.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -81,3 +44,44 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(struct stream *stream) +{ + size_t i, j, n; + TYPE v, *p; + do { + if (equal) { + n = stream->ptr / stream->pixel_size; + for (i = 0; i < n; i++) { + p = (TYPE *)(stream->buf) + i * stream->n_chan; + v = posmod(*p, (TYPE)2); + v = v > 1 ? 2 - v : v; + if (spiral) + v = (v > (TYPE)0.5 ? 1 - v : v) * 2; + for (j = 0; j < stream->n_chan; j++) + p[j] = v; + } + n *= stream->pixel_size; + } else { + n = stream->ptr / stream->chan_size; + for (i = 0; i < n; i++) { + p = (TYPE *)(stream->buf) + i; + v = posmod(*p, (TYPE)2); + v = v > 1 ? 2 - v : v; + if (spiral) + v = (v > (TYPE)0.5 ? 1 - v : v) * 2; + *p = v; + } + n *= stream->chan_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); +} + +#endif diff --git a/src/blind-unpremultiply.c b/src/blind-unpremultiply.c @@ -1,4 +1,5 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-xyz]") @@ -7,35 +8,8 @@ static int skip_x = 0; static int skip_y = 0; static int skip_z = 0; -#define PROCESS(TYPE, SUFFIX)\ - static void\ - process_##SUFFIX(struct stream *stream)\ - {\ - size_t i, n;\ - TYPE a;\ - do {\ - n = stream->ptr / stream->pixel_size;\ - for (i = 0; i < n; i++) {\ - a = ((TYPE *)(stream->buf))[4 * i + 3];\ - if (!a)\ - continue;\ - if (!skip_x)\ - ((TYPE *)(stream->buf))[4 * i + 0] /= a;\ - if (!skip_y)\ - ((TYPE *)(stream->buf))[4 * i + 1] /= a;\ - if (!skip_z)\ - ((TYPE *)(stream->buf))[4 * i + 2] /= 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) +#define FILE "blind-unpremultiply.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -74,3 +48,33 @@ main(int argc, char *argv[]) process(&stream); return 0; } + +#else + +static void +PROCESS(struct stream *stream) +{ + size_t i, n; + TYPE a; + do { + n = stream->ptr / stream->pixel_size; + for (i = 0; i < n; i++) { + a = ((TYPE *)(stream->buf))[4 * i + 3]; + if (!a) + continue; + if (!skip_x) + ((TYPE *)(stream->buf))[4 * i + 0] /= a; + if (!skip_y) + ((TYPE *)(stream->buf))[4 * i + 1] /= a; + if (!skip_z) + ((TYPE *)(stream->buf))[4 * i + 2] /= 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); +} + +#endif diff --git a/src/blind-vector-projection.c b/src/blind-vector-projection.c @@ -1,45 +1,13 @@ /* See LICENSE file for copyright and license details. */ +#ifndef TYPE #include "common.h" USAGE("[-r | -s] plane-stream") static int level = 1; -#define PROCESS(TYPE, SUFFIX)\ - static void\ - process_##SUFFIX(struct stream *left, struct stream *right, size_t n)\ - {\ - size_t i;\ - TYPE *lx, *ly, *lz, *la, rx, ry, rz, ra, x, y, z, a, norm;\ - for (i = 0; i < n; i += 4 * sizeof(TYPE)) {\ - lx = ((TYPE *)(left->buf + i)) + 0, rx = ((TYPE *)(right->buf + i))[0];\ - ly = ((TYPE *)(left->buf + i)) + 1, ry = ((TYPE *)(right->buf + i))[1];\ - lz = ((TYPE *)(left->buf + i)) + 2, rz = ((TYPE *)(right->buf + i))[2];\ - la = ((TYPE *)(left->buf + i)) + 3, ra = ((TYPE *)(right->buf + i))[3];\ - norm = rx * rx + ry * ry + rz * rz + ra * ra;\ - norm = sqrt(norm);\ - x = y = z = a = *lx * rx + *ly * ry + *lz * rz + *la * ra;\ - if (level) {\ - x *= rx;\ - y *= ry;\ - z *= rz;\ - a *= rz;\ - if (level > 1) {\ - x = *lx - x;\ - y = *ly - y;\ - z = *lz - z;\ - a = *la - a;\ - }\ - }\ - *lx = x;\ - *ly = y;\ - *lz = z;\ - *la = a;\ - }\ - } - -PROCESS(double, lf) -PROCESS(float, f) +#define FILE "blind-vector-projection.c" +#include "define-functions.h" int main(int argc, char *argv[]) @@ -80,3 +48,39 @@ main(int argc, char *argv[]) process_two_streams(&left, &right, STDOUT_FILENO, "<stdout>", process); return 0; } + +#else + +static void +PROCESS(struct stream *left, struct stream *right, size_t n) +{ + size_t i; + TYPE *lx, *ly, *lz, *la, rx, ry, rz, ra, x, y, z, a, norm; + for (i = 0; i < n; i += 4 * sizeof(TYPE)) { + lx = ((TYPE *)(left->buf + i)) + 0, rx = ((TYPE *)(right->buf + i))[0]; + ly = ((TYPE *)(left->buf + i)) + 1, ry = ((TYPE *)(right->buf + i))[1]; + lz = ((TYPE *)(left->buf + i)) + 2, rz = ((TYPE *)(right->buf + i))[2]; + la = ((TYPE *)(left->buf + i)) + 3, ra = ((TYPE *)(right->buf + i))[3]; + norm = rx * rx + ry * ry + rz * rz + ra * ra; + norm = sqrt(norm); + x = y = z = a = *lx * rx + *ly * ry + *lz * rz + *la * ra; + if (level) { + x *= rx; + y *= ry; + z *= rz; + a *= rz; + if (level > 1) { + x = *lx - x; + y = *ly - y; + z = *lz - z; + a = *la - a; + } + } + *lx = x; + *ly = y; + *lz = z; + *la = a; + } +} + +#endif diff --git a/src/common.h b/src/common.h @@ -64,3 +64,7 @@ #ifndef CMSG_LEN # define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct cmsghdr)) + (len)) #endif + +#if !defined(PIPE_BUF) +# define PIPE_BUF BUFSIZ +#endif diff --git a/src/define-functions.h b/src/define-functions.h @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ + +#define PROCESS process_lf +#define TYPE double +#include FILE +#undef PROCESS +#undef TYPE + +#define PROCESS process_f +#define TYPE float +#include FILE +#undef PROCESS +#undef TYPE