commit 076d0dc569608c276b25742605d35b0ac44dbf46
Author: Mattias Andrée <maandree_AT_kth.se>
AuthorDate: Sun Jan 15 20:52:36 2017 +0100
Commit: Mattias Andrée <maandree_AT_kth.se>
CommitDate: Sun Jan 15 20:52:36 2017 +0100
Fix errors
Signed-off-by: Mattias Andrée <maandree_AT_kth.se>
diff --git a/TODO b/TODO
index 943f8a0..ace6836 100644
--- a/TODO
+++ b/TODO
_AT_@ -10,17 +10,10 @@ blind-apply-kernel apply a convolution matrix
blind-find-frame a graphical tool for locating frames, should highlight key frames
UNTESTED:
- blind-colour-srgb
blind-crop
blind-cut
- blind-dissolve
blind-extend
blind-from-text
blind-gauss-blur
- blind-invert-luma
blind-rewrite-head
- blind-set-alpha
- blind-set-luma
- blind-set-saturation
- blind-split
blind-to-text
diff --git a/src/blind-arithm.c b/src/blind-arithm.c
index 015df42..d74fbf8 100644
--- a/src/blind-arithm.c
+++ b/src/blind-arithm.c
_AT_@ -8,7 +8,12 @@
#include <string.h>
#include <unistd.h>
-USAGE("operation right-hand-stream")
+USAGE("[-ayxz] operation right-hand-stream")
+
+static int skip_a = 0;
+static int skip_x = 0;
+static int skip_y = 0;
+static int skip_z = 0;
/* Because the syntax for a function returning a function pointer is disgusting. */
typedef void (*process_func)(struct stream *left, struct stream *right, size_t n);
_AT_@ -30,14 +35,22 @@ typedef void (*process_func)(struct stream *left, struct stream *right, size_t n
size_t i;\
double *lh, rh;\
for (i = 0; i < n; i += 4 * sizeof(double)) {\
- lh = ((double *)(left->buf + i)) + 0, rh = ((double *)(right->buf + i))[0];\
- ALGO;\
- lh = ((double *)(left->buf + i)) + 1, rh = ((double *)(right->buf + i))[1];\
- ALGO;\
- lh = ((double *)(left->buf + i)) + 2, rh = ((double *)(right->buf + i))[2];\
- ALGO;\
- lh = ((double *)(left->buf + i)) + 3, rh = ((double *)(right->buf + i))[3];\
- ALGO;\
+ if (!skip_x) {\
+ lh = ((double *)(left->buf + i)) + 0, rh = ((double *)(right->buf + i))[0];\
+ ALGO;\
+ }\
+ if (!skip_y) {\
+ lh = ((double *)(left->buf + i)) + 1, rh = ((double *)(right->buf + i))[1];\
+ ALGO;\
+ }\
+ if (!skip_z) {\
+ lh = ((double *)(left->buf + i)) + 2, rh = ((double *)(right->buf + i))[2];\
+ ALGO;\
+ }\
+ if (!skip_a) {\
+ lh = ((double *)(left->buf + i)) + 3, rh = ((double *)(right->buf + i))[3];\
+ ALGO;\
+ }\
}\
}
LIST_OPERATORS
_AT_@ -60,7 +73,25 @@ main(int argc, char *argv[])
struct stream left, right;
process_func process = NULL;
- ENOFLAGS(argc != 2);
+ ARGBEGIN {
+ case 'a':
+ skip_a = 1;
+ break;
+ case 'x':
+ skip_x = 1;
+ break;
+ case 'y':
+ skip_y = 1;
+ break;
+ case 'z':
+ skip_z = 1;
+ break;
+ default:
+ usage();
+ } ARGEND;
+
+ if (argc != 2)
+ usage();
left.file = "<stdin>";
left.fd = STDIN_FILENO;
diff --git a/src/blind-dissolve.c b/src/blind-dissolve.c
index 83b9091..1873975 100644
--- a/src/blind-dissolve.c
+++ b/src/blind-dissolve.c
_AT_@ -55,14 +55,14 @@ main(int argc, char *argv[])
stream.fd = STDIN_FILENO;
stream.file = "<stdin>";
einit_stream(&stream);
- fprint_stream_head(stdout, &stream);
- efflush(stdout, "<stdout>");
if (!strcmp(stream.pixfmt, "xyza"))
process = reverse ? process_xyza_r : process_xyza;
else
eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
+ fprint_stream_head(stdout, &stream);
+ efflush(stdout, "<stdout>");
fmd = fm = stream.frames - 1;
process_each_frame_segmented(&stream, STDOUT_FILENO, "<stdout>", process);
diff --git a/src/blind-invert-luma.c b/src/blind-invert-luma.c
index aa3b260..c83b8dc 100644
--- a/src/blind-invert-luma.c
+++ b/src/blind-invert-luma.c
_AT_@ -7,19 +7,29 @@
#include <string.h>
#include <unistd.h>
-USAGE("[-i] mask-stream")
+USAGE("[-iw] mask-stream")
static void
process_xyza(struct stream *colour, struct stream *mask, size_t n)
{
size_t i;
- double w, y;
+ double w, y, yo, X, Z;
+ X = D65_XYY_X / D65_XYY_Y;
+ Z = 1 / D65_XYY_Y - 1 - X;
for (i = 0; i < n; i += colour->pixel_size) {
w = ((double *)(mask->buf + i))[1];
w *= ((double *)(mask->buf + i))[3];
- y = ((double *)(colour->buf + i))[3];
- y = (1 - y) * w + y * (1 - w);
- ((double *)(colour->buf + i))[3] = y;
+ yo = ((double *)(colour->buf + i))[1];
+ y = (1 - yo) * w + yo * (1 - w);
+ ((double *)(colour->buf + i))[0] += (y - yo) * X;
+ ((double *)(colour->buf + i))[1] = y;
+ ((double *)(colour->buf + i))[2] += (y - yo) * Z;
+ /*
+ * Explaination:
+ * Y is the luma and ((X / Xn - Y / Yn), (Z / Zn - Y / Yn))
+ * is the chroma (according to CIELAB), where (Xn, Yn, Zn)
+ * is the white point.
+ */
}
}
_AT_@ -27,20 +37,60 @@ static void
process_xyza_i(struct stream *colour, struct stream *mask, size_t n)
{
size_t i;
- double w, y;
+ double w, y, yo, X, Z;
+ X = D65_XYY_X / D65_XYY_Y;
+ Z = 1 / D65_XYY_Y - 1 - X;
for (i = 0; i < n; i += colour->pixel_size) {
w = 1 - ((double *)(mask->buf + i))[1];
w *= ((double *)(mask->buf + i))[3];
- y = ((double *)(colour->buf + i))[3];
- y = (1 - y) * w + y * (1 - w);
- ((double *)(colour->buf + i))[3] = y;
+ yo = ((double *)(colour->buf + i))[1];
+ y = (1 - yo) * w + yo * (1 - w);
+ ((double *)(colour->buf + i))[0] += (y - yo) * X;
+ ((double *)(colour->buf + i))[1] = y;
+ ((double *)(colour->buf + i))[2] += (y - yo) * Z;
+ }
+}
+
+static void
+process_xyza_w(struct stream *colour, struct stream *mask, size_t n)
+{
+ size_t i;
+ double w, y, yo, X, Z;
+ for (i = 0; i < n; i += colour->pixel_size) {
+ X = ((double *)(mask->buf + i))[0];
+ Z = ((double *)(mask->buf + i))[2];
+ w = ((double *)(mask->buf + i))[1];
+ w *= ((double *)(mask->buf + i))[3];
+ yo = ((double *)(colour->buf + i))[1];
+ y = (1 - yo) * w + yo * (1 - w);
+ ((double *)(colour->buf + i))[0] += (y - yo) * X;
+ ((double *)(colour->buf + i))[1] = y;
+ ((double *)(colour->buf + i))[2] += (y - yo) * Z;
+ }
+}
+
+static void
+process_xyza_iw(struct stream *colour, struct stream *mask, size_t n)
+{
+ size_t i;
+ double w, y, yo, X, Z;
+ for (i = 0; i < n; i += colour->pixel_size) {
+ X = ((double *)(mask->buf + i))[0];
+ Z = ((double *)(mask->buf + i))[2];
+ w = 1 - ((double *)(mask->buf + i))[1];
+ w *= ((double *)(mask->buf + i))[3];
+ yo = ((double *)(colour->buf + i))[1];
+ y = (1 - yo) * w + yo * (1 - w);
+ ((double *)(colour->buf + i))[0] += (y - yo) * X;
+ ((double *)(colour->buf + i))[1] = y;
+ ((double *)(colour->buf + i))[2] += (y - yo) * Z;
}
}
int
main(int argc, char *argv[])
{
- int invert = 0;
+ int invert = 0, whitepoint = 0;
struct stream colour, mask;
void (*process)(struct stream *colour, struct stream *mask, size_t n) = NULL;
_AT_@ -48,6 +98,9 @@ main(int argc, char *argv[])
case 'i':
invert = 1;
break;
+ case 'w':
+ whitepoint = 1;
+ break;
default:
usage();
} ARGEND;
_AT_@ -64,10 +117,13 @@ main(int argc, char *argv[])
einit_stream(&mask);
if (!strcmp(colour.pixfmt, "xyza"))
- process = invert ? process_xyza_i : process_xyza;
+ process = invert ? whitepoint ? process_xyza_iw : process_xyza_i
+ : whitepoint ? process_xyza_w : process_xyza;
else
eprintf("pixel format %s is not supported, try xyza\n", colour.pixfmt);
+ fprint_stream_head(stdout, &colour);
+ efflush(stdout, "<stdout>");
process_two_streams(&colour, &mask, STDOUT_FILENO, "<stdout>", process);
return 0;
}
diff --git a/src/blind-set-alpha.c b/src/blind-set-alpha.c
index 2e80154..a7d2404 100644
--- a/src/blind-set-alpha.c
+++ b/src/blind-set-alpha.c
_AT_@ -64,6 +64,8 @@ main(int argc, char *argv[])
else
eprintf("pixel format %s is not supported, try xyza\n", colour.pixfmt);
+ fprint_stream_head(stdout, &colour);
+ efflush(stdout, "<stdout>");
process_two_streams(&colour, &alpha, STDOUT_FILENO, "<stdout>", process);
return 0;
}
diff --git a/src/blind-set-luma.c b/src/blind-set-luma.c
index 4500645..71bd59c 100644
--- a/src/blind-set-luma.c
+++ b/src/blind-set-luma.c
_AT_@ -13,11 +13,44 @@ static void
process_xyza(struct stream *colour, struct stream *luma, size_t n)
{
size_t i;
- double a;
+ double a, y;
for (i = 0; i < n; i += colour->pixel_size) {
a = ((double *)(luma->buf + i))[1];
a *= ((double *)(luma->buf + i))[3];
- ((double *)(colour->buf + i))[1] *= a;
+ y = ((double *)(colour->buf + i))[1];
+ ((double *)(colour->buf + i))[0] += y * a - y;
+ ((double *)(colour->buf + i))[1] = y * a;
+ ((double *)(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:
+ * 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⎠
+ */
}
}
_AT_@ -42,6 +75,8 @@ main(int argc, char *argv[])
else
eprintf("pixel format %s is not supported, try xyza\n", colour.pixfmt);
+ fprint_stream_head(stdout, &colour);
+ efflush(stdout, "<stdout>");
process_two_streams(&colour, &luma, STDOUT_FILENO, "<stdout>", process);
return 0;
}
diff --git a/src/blind-set-saturation.c b/src/blind-set-saturation.c
index 1d3ed83..3dffff0 100644
--- a/src/blind-set-saturation.c
+++ b/src/blind-set-saturation.c
_AT_@ -13,16 +13,23 @@ static void
process_xyza(struct stream *colour, struct stream *satur, size_t n)
{
size_t i;
- double s, *x, *z, X, Z;
+ double s, *x, y, *z, X, Z;
X = D65_XYY_X / D65_XYY_Y;
Z = 1 / D65_XYY_Y - 1 - X;
for (i = 0; i < n; i += colour->pixel_size) {
s = ((double *)(satur->buf + i))[1];
s *= ((double *)(satur->buf + i))[3];
x = ((double *)(colour->buf + i)) + 0;
+ y = ((double *)(colour->buf + i))[1];
z = ((double *)(colour->buf + i)) + 2;
- *x = (*x - X) * s + X;
- *z = (*z - Z) * s + Z;
+ *x = ((*x / X - y) * s + y) * X;
+ *z = ((*z / Z - y) * s + y) * Z;
+ /*
+ * Explaination:
+ * Y is the luma and ((X / Xn - Y / Yn), (Z / Zn - Y / Yn))
+ * is the chroma (according to CIELAB), where (Xn, Yn, Zn)
+ * is the white point.
+ */
}
}
_AT_@ -30,16 +37,17 @@ static void
process_xyza_w(struct stream *colour, struct stream *satur, size_t n)
{
size_t i;
- double s, *x, *z, X, Z;
+ double s, *x, y, *z, X, Z;
for (i = 0; i < n; i += colour->pixel_size) {
X = ((double *)(satur->buf + i))[0];
Z = ((double *)(satur->buf + i))[2];
s = ((double *)(satur->buf + i))[1];
s *= ((double *)(satur->buf + i))[3];
x = ((double *)(colour->buf + i)) + 0;
+ y = ((double *)(colour->buf + i))[1];
z = ((double *)(colour->buf + i)) + 2;
- *x = (*x - X) * s + X;
- *z = (*z - Z) * s + Z;
+ *x = ((*x / X - y) * s + y) * X;
+ *z = ((*z / Z - y) * s + y) * Z;
}
}
_AT_@ -74,6 +82,8 @@ main(int argc, char *argv[])
else
eprintf("pixel format %s is not supported, try xyza\n", colour.pixfmt);
+ fprint_stream_head(stdout, &colour);
+ efflush(stdout, "<stdout>");
process_two_streams(&colour, &satur, STDOUT_FILENO, "<stdout>", process);
return 0;
}
Received on Sun Jan 15 2017 - 20:52:47 CET
This archive was generated by hypermail 2.3.0
: Sun Jan 15 2017 - 21:00:17 CET