commit ffeba5cae6ebf01f421e11eee2c4d050da0bb3f3
parent bd8018a737281770159231c060f3bfd30788a430
Author: Mattias Andrée <maandree@kth.se>
Date: Wed, 26 Jul 2017 16:26:05 +0200
blind*-mean: add -d and replace power with power-stream
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat:
7 files changed, 169 insertions(+), 103 deletions(-)
diff --git a/TODO b/TODO
@@ -1,5 +1,3 @@
-blind-*-mean: replace power with power-stream
-
blind-transform affine transformation by matrix multiplication, -[xy] for tiling, -s for
improve quality on downscaling (pixels' neighbours must not change)
blind-apply-map remap pixels (distortion) using the X and Y values, -[xy] for tiling, -s for
diff --git a/man/blind-mean.1 b/man/blind-mean.1
@@ -3,14 +3,14 @@
blind-mean - Calcuate the mean over videos for each pixel in each frame
.SH SYNOPSIS
.B blind-mean
-[-g | -h | -H | -i | -l
-.I power
+[-d | -g | -h | -H | -i | -l
+.I power-stream
| -L | -p
-.I power
+.I power-stream
| -s
-.I power
+.I power-stream
| -v | -z
-.IR power ]
+.IR power-stream ]
.I stream-1
.IR stream-2 \ ...
.SH DESCRIPTION
@@ -26,24 +26,29 @@ Unless otherwise specified, the arithmetic mean
is calculated.
.SH OPTIONS
.TP
+.B -d
+Calculate the standard deviation.
+.TP
.B -g
Calculate the geometric mean.
.TP
.B -h
Calculate the harmonic mean.
.TP
-.B -i
-Calculate the identric mean.
-.TP
.B -H
Calculate the Heronian mean.
No arguments after
.I stream-2
are allowed if this flag is used.
.TP
-.BR -l \ \fIpower\fP
-Calculate the Lehmer mean with the specified
-.IR power .
+.B -i
+Calculate the identric mean.
+.TP
+.BR -l \ \fIpower-stream\fP
+Calculate the Lehmer mean with the power
+specified in the same frame and pixel in
+the video
+.IR power-stream .
.TP
.B -L
Calculate the logarithmic mean.
@@ -51,15 +56,17 @@ No arguments after
.I stream-2
are allowed if this flag is used.
.TP
-.BR -p \ \fIpower\fP
+.BR -p \ \fIpower-stream\fP
Calculate the power mean (Hölder mean) with
-the specified
-.IR power .
+the power specified in the same frame and
+pixel in the video
+.IR power-stream .
.TP
-.BR -s \ \fIpower\fP
-Calculate the Stolarsky mean with
-the specified
-.IR power .
+.BR -s \ \fIpower-stream\fP
+Calculate the Stolarsky mean with the power
+specified in the same frame and pixel in
+the video
+.IR power-stream .
No arguments after
.I stream-2
are allowed if this flag is used.
@@ -67,10 +74,11 @@ are allowed if this flag is used.
.B -v
Calculate the variance.
.TP
-.BR -z \ \fIpower\fP
-Calculate the Heinz meanw ith
-the specified
-.IR power .
+.BR -z \ \fIpower-stream\fP
+Calculate the Heinz mean with the power
+specified in the same frame and pixel in
+the video
+.IR power-stream .
No arguments after
.I stream-2
are allowed if this flag is used.
diff --git a/man/blind-spatial-mean.1 b/man/blind-spatial-mean.1
@@ -3,10 +3,10 @@
blind-spatial-mean - Calculate the mean over all pixel for each frame in a video
.SH SYNOPSIS
.B blind-spatial-mean
-[-g | -h | -l
-.I power
+[-d | -g | -h | -l
+.I power-stream
| -p
-.I power
+.I power-stream
| -v]
.SH DESCRIPTION
.B blind-spatial-mean
@@ -19,20 +19,26 @@ Unless otherwise specified, the arithmetic mean
is calculated.
.SH OPTIONS
.TP
+.B -d
+Calculate the standard deviation.
+.TP
.B -g
Calculate the geometric mean.
.TP
.B -h
Calculate the harmonic mean.
.TP
-.BR -l \ \fIpower\fP
-Calculate the Lehmer mean with the specified
-.IR power .
+.BR -l \ \fIpower-stream\fP
+Calculate the Lehmer mean with the power
+specified in the same single-pixel frame
+in the video
+.IR power-stream .
.TP
-.BR -p \ \fIpower\fP
+.BR -p \ \fIpower-stream\fP
Calculate the power mean (Hölder mean) with
-the specified
-.IR power .
+the power specified in the same single-pixel
+frame in the video
+.IR power-stream .
.TP
.B -v
Calculate the variance.
diff --git a/man/blind-temporal-mean.1 b/man/blind-temporal-mean.1
@@ -3,10 +3,10 @@
blind-temporal-mean - Calculate the mean over all frames in a video for each pixel
.SH SYNOPSIS
.B blind-temporal-mean
-[-g | -h | -l
-.I power
+[-d | -g | -h | -l
+.I power-stream
| -p
-.I power
+.I power-stream
| -v]
.SH DESCRIPTION
.B blind-temporal-mean
@@ -19,20 +19,26 @@ Unless otherwise specified, the arithmetic mean
is calculated.
.SH OPTIONS
.TP
+.B -d
+Calculate the standard deviation.
+.TP
.B -g
Calculate the geometric mean.
.TP
.B -h
Calculate the harmonic mean.
.TP
-.BR -l \ \fIpower\fP
-Calculate the Lehmer mean with the specified
-.IR power .
+.BR -l \ \fIpower-stream\fP
+Calculate the Lehmer mean with the power
+specified in the same pixel in the single-frame
+video
+.IR power-stream .
.TP
-.BR -p \ \fIpower\fP
+.BR -p \ \fIpower-stream\fP
Calculate the power mean (Hölder mean) with
-the specified
-.IR power .
+the power specified in the same pixel in the
+single-frame video
+.IR power-stream .
.TP
.B -v
Calculate the variance.
@@ -40,10 +46,13 @@ Calculate the variance.
.B blind-temporal-mean
requires enough free memory to load two full frames memory.
A frame requires 32 bytes per pixel it contains. If
-.B -l
+.B -p
or
.B -v
is used, enough free memory to load three full frames
+memory is required. If
+.B -l
+is used, enough free memory to load four full frames
memory is required.
.P
.B blind-temporal-mean
diff --git a/src/blind-mean.c b/src/blind-mean.c
@@ -1,7 +1,7 @@
/* See LICENSE file for copyright and license details. */
#include "common.h"
-USAGE("[-g | -h | -H | -i | -l power | -L | -p power | -s power | -v | -z power] stream-1 stream-2 ...")
+USAGE("[-d | -g | -h | -H | -i | -l power-stream | -L | -p power-stream | -s power-stream | -v | -z power] stream-1 stream-2 ...")
/* TODO add [-w weight-stream] for [-ghlpv] */
/* Because the syntax for a function returning a function pointer is disgusting. */
@@ -18,6 +18,9 @@ typedef void (*process_func)(struct stream *streams, size_t n_streams, size_t n)
#define LIST_MEANS(TYPE)\
/* [default] arithmetic mean */\
X(ARITHMETIC, arithmetic, sn = (TYPE)1 / sn, 0, img += val, img *= sn) \
+ /* standard deviation */\
+ X(STANDARD_DEVIATION, sd, sn = (TYPE)1 / sn, 0, (img += val * val, aux += val),\
+ img = nnpow((img - aux * aux * sn) * sn, (TYPE)0.5))\
/* geometric mean */\
X(GEOMETRIC, geometric, sn = (TYPE)1 / sn, 1, img *= val, img = nnpow(img, sn))\
/* harmonic mean */\
@@ -30,32 +33,32 @@ typedef void (*process_func)(struct stream *streams, size_t n_streams, size_t n)
img = auxs[0] == auxs[1] ? auxs[0] :\
nnpow(nnpow(auxs[0], auxs[0]) / nnpow(auxs[1], auxs[1]), auxs[0] - auxs[1]) * a)\
/* Lehmer mean */\
- X(LEHMER, lehmer, (a = (TYPE)power, b = a - (TYPE)1), 0,\
- (img += nnpow(val, a), aux += nnpow(val, b)), img /= aux)\
+ X(LEHMER, lehmer,, 0, (img += nnpow(val, *pows), aux += nnpow(val, *pows - (TYPE)1)), img /= aux)\
/* logarithmic mean */\
X(LOGARITHMIC, logarithmic,, 0, auxs[j] = val,\
img = auxs[0] == auxs[1] ? auxs[0] : (!auxs[0] || !auxs[1]) ? (TYPE)0 :\
(auxs[1] - auxs[0]) / log(auxs[1] / auxs[0]))\
/* power mean (Hölder mean) (m = 2 for root square mean; m = 3 for cubic mean) */\
- X(POWER, power, (a = (TYPE)power, b = (TYPE)(1. / power), sn = (TYPE)1 / sn), 0,\
- img += nnpow(val, a), img = nnpow(img, b) * sn)\
+ X(POWER, power, sn = (TYPE)1 / sn, 0,\
+ img += nnpow(val, *pows), img = nnpow(img, (TYPE)1 / *pows) * sn)\
/* Stolarsky mean */\
- X(STOLARSKY, stolarsky, (a = (TYPE)power, b = (TYPE)(1. / (power - 1.))), 0, auxs[j] = val,\
+ X(STOLARSKY, stolarsky,, 0, auxs[j] = val,\
img = auxs[0] == auxs[1] ? auxs[0] :\
- nnpow((nnpow(auxs[0], auxs[0]) - nnpow(auxs[1], auxs[1])) /\
- (a * (auxs[0] - auxs[1])), b))\
+ nnpow((nnpow(auxs[0], *pows) - nnpow(auxs[1], *pows)) /\
+ (*pows * (auxs[0] - auxs[1])), (TYPE)1 / (*pows - (TYPE)1)))\
/* variance */\
X(VARIANCE, variance, sn = (TYPE)1 / sn, 0, (img += val * val, aux += val),\
img = (img - aux * aux * sn) * sn)\
/* Heinz mean */\
- X(HEINZ, heinz, (a = (TYPE)power, b = (TYPE)1 - a), 0, auxs[j] = val,\
- img = (nnpow(auxs[0], a) * nnpow(auxs[1], b) + nnpow(auxs[0], b) * nnpow(auxs[1], 0)) / (TYPE)2)
+ X(HEINZ, heinz,, 0, auxs[j] = val,\
+ img = (nnpow(auxs[0], *pows) * nnpow(auxs[1], (TYPE)1 - *pows) +\
+ nnpow(auxs[0], (TYPE)1 - *pows) * nnpow(auxs[1], *pows)) / (TYPE)2)
#define X(V, ...) V,
enum method { LIST_MEANS() };
#undef X
-static double power;
+static const char *power_file = NULL;
#define aux (*auxs)
#define MAKE_PROCESS(PIXFMT, TYPE,\
@@ -64,9 +67,12 @@ static double power;
process_##PIXFMT##_##NAME(struct stream *streams, size_t n_streams, size_t n)\
{\
size_t i, j;\
- TYPE img, auxs[2], val, a, b, sn = (TYPE)n_streams;\
+ TYPE img, auxs[2], val, a, sn;\
+ TYPE *pows = power_file ? (TYPE *)(streams[n_streams - 1].buf) : NULL;\
+ n_streams -= (size_t)!!power_file;\
+ sn = (TYPE)n_streams;\
INIT;\
- for (i = 0; i < n; i += sizeof(TYPE)) {\
+ for (i = 0; i < n; i += sizeof(TYPE), pows++) {\
img = auxs[0] = auxs[1] = INITIAL;\
for (j = 0; j < n_streams; j++) {\
val = *(TYPE *)(streams[j].buf + i);\
@@ -75,7 +81,7 @@ static double power;
FINALISE_SUBCELL;\
*(TYPE *)(streams->buf + i) = img;\
}\
- (void) aux, (void) a, (void) b, (void) sn;\
+ (void) aux, (void) a, (void) pows, (void) sn;\
}
#define X(...) MAKE_PROCESS(lf, double, __VA_ARGS__)
LIST_MEANS(double)
@@ -103,7 +109,11 @@ main(int argc, char *argv[])
enum method method = ARITHMETIC;
int i, two = 0;
+
ARGBEGIN {
+ case 'd':
+ method = STANDARD_DEVIATION;
+ break;
case 'g':
method = GEOMETRIC;
break;
@@ -120,7 +130,7 @@ main(int argc, char *argv[])
break;
case 'l':
method = LEHMER;
- power = etolf_flag('l', UARGF());
+ power_file = UARGF();
break;
case 'L':
method = LOGARITHMIC;
@@ -128,12 +138,12 @@ main(int argc, char *argv[])
break;
case 'p':
method = POWER;
- power = etolf_flag('p', UARGF());
+ power_file = UARGF();
break;
case 's':
method = STOLARSKY;
two = 1;
- power = etolf_flag('s', UARGF());
+ power_file = UARGF();
break;
case 'v':
method = VARIANCE;
@@ -141,7 +151,7 @@ main(int argc, char *argv[])
case 'z':
method = HEINZ;
two = 1;
- power = etolf_flag('z', UARGF());
+ power_file = UARGF();
break;
default:
usage();
@@ -150,12 +160,14 @@ main(int argc, char *argv[])
if (argc < 2 || (argc > 2 && two))
usage();
- streams = alloca((size_t)argc * sizeof(*streams));
+ streams = alloca((size_t)(argc + !!power_file) * sizeof(*streams));
for (i = 0; i < argc; i++) {
eopen_stream(streams + i, argv[i]);
if (streams[i].frames && streams[i].frames < frames)
frames = streams[i].frames;
}
+ if (power_file != NULL)
+ eopen_stream(streams + argc, power_file);
if (streams->encoding == DOUBLE)
process = process_functions_lf[method];
@@ -166,6 +178,7 @@ main(int argc, char *argv[])
fprint_stream_head(stdout, streams);
efflush(stdout, "<stdout>");
streams->frames = tmp;
- process_multiple_streams(streams, (size_t)argc, STDOUT_FILENO, "<stdout>", 1, process);
+ process_multiple_streams(streams, (size_t)(argc + !!power_file),
+ STDOUT_FILENO, "<stdout>", 1, process);
return 0;
}
diff --git a/src/blind-spatial-mean.c b/src/blind-spatial-mean.c
@@ -1,12 +1,13 @@
/* See LICENSE file for copyright and license details. */
#include "common.h"
-USAGE("[-g | -h | -l power | -p power | -v]")
+USAGE("[-d | -g | -h | -l power-stream | -p power-stream | -v]")
/* TODO add [-w weight-stream] for [-ghlpv] */
/* Because the syntax for a function returning a function pointer is disgusting. */
typedef void (*process_func)(struct stream *stream);
+#define C (j & 3)
/*
* X-parameter 1: method enum value
* X-parameter 2: identifier-friendly name
@@ -17,37 +18,41 @@ typedef void (*process_func)(struct stream *stream);
*/
#define LIST_MEANS(TYPE)\
/* [default] arithmetic mean */\
- X(ARITHMETIC, arithmetic,, 0, img[j & 3] += *buf, img[j & 3] /= pixels)\
+ X(ARITHMETIC, arithmetic,, 0, img[C] += *buf, img[C] /= pixels)\
+ /* standard deviation */\
+ X(STANDARD_DEVIATION, sd,, 0, (img[C] += *buf * *buf, aux[C] += *buf),\
+ img[C] = nnpow((img[C] - aux[C] * aux[C] / pixels) / pixels, (TYPE)0.5)) \
/* geometric mean */\
- X(GEOMETRIC, geometric,, 1, img[j & 3] *= *buf, img[j & 3] = nnpow(img[j & 3], 1 / pixels))\
+ X(GEOMETRIC, geometric,, 1, img[C] *= *buf, img[C] = nnpow(img[C], 1 / pixels))\
/* harmonic mean */\
- X(HARMONIC, harmonic,, 0, img[j & 3] += (TYPE)1 / *buf, img[j & 3] = pixels / img[j & 3])\
+ X(HARMONIC, harmonic,, 0, img[C] += (TYPE)1 / *buf, img[C] = pixels / img[C])\
/* Lehmer mean */\
- X(LEHMER, lehmer, (a = (TYPE)power, b = a - (TYPE)1), 0,\
- (img[j & 3] += nnpow(*buf, a), aux[j & 3] += nnpow(*buf, b)), img[j & 3] /= aux[j & 3])\
+ X(LEHMER, lehmer, (a[0] = powers[0] - (TYPE)1, a[1] = powers[1] - (TYPE)1,\
+ a[2] = powers[2] - (TYPE)1, a[3] = powers[3] - (TYPE)1), 0,\
+ (img[C] += nnpow(*buf, powers[C]), aux[C] += nnpow(*buf, a[C])), img[C] /= aux[C])\
/* power mean (Hölder mean) (m = 2 for root square mean; m = 3 for cubic mean) */\
- X(POWER, power, a = (TYPE)power, 0, img[j & 3] += nnpow(*buf, a),\
- img[j & 3] = nnpow(img[j & 3], (TYPE)(1. / power)) / pixels)\
+ X(POWER, power,, 0, img[C] += nnpow(*buf, powers[C]),\
+ img[C] = nnpow(img[C], (TYPE)1 / powers[C]) / pixels)\
/* variance */\
- X(VARIANCE, variance,, 0, (img[j & 3] += *buf * *buf, aux[j & 3] += *buf),\
- img[j & 3] = (img[j & 3] - aux[j & 3] * aux[j & 3] / pixels) / pixels)
+ X(VARIANCE, variance,, 0, (img[C] += *buf * *buf, aux[C] += *buf),\
+ img[C] = (img[C] - aux[C] * aux[C] / pixels) / pixels)
#define X(V, ...) V,
enum method { LIST_MEANS() };
#undef X
-static double power;
+static struct stream power;
+static const char *power_file = NULL;
#define MAKE_PROCESS(PIXFMT, TYPE,\
_1, NAME, INIT, INITIAL, PROCESS_SUBCELL, FINALISE_SUBCELL)\
static void\
process_##PIXFMT##_##NAME(struct stream *stream)\
{\
- TYPE img[4], aux[4], *buf, a, b;\
+ TYPE img[4], aux[4], *buf, a[4], powers[4];\
TYPE pixels = (TYPE)(stream->frame_size / sizeof(img));\
size_t i, n, j = 0, m = stream->frame_size / sizeof(*img);\
int first = 1;\
- INIT;\
do {\
n = stream->ptr / stream->pixel_size * stream->n_chan;\
buf = (TYPE *)(stream->buf);\
@@ -60,6 +65,9 @@ static double power;
ewriteall(STDOUT_FILENO, img, sizeof(img), "<stdout>");\
}\
first = 0;\
+ if (power_file && !eread_frame(&power, powers))\
+ return;\
+ INIT;\
img[0] = aux[0] = INITIAL;\
img[1] = aux[1] = INITIAL;\
img[2] = aux[2] = INITIAL;\
@@ -75,7 +83,7 @@ static double power;
FINALISE_SUBCELL;\
ewriteall(STDOUT_FILENO, img, sizeof(img), "<stdout>");\
}\
- (void) aux, (void) a, (void) b, (void) pixels;\
+ (void) aux, (void) a, (void) powers, (void) pixels;\
}
#define X(...) MAKE_PROCESS(lf, double, __VA_ARGS__)
LIST_MEANS(double)
@@ -84,6 +92,7 @@ LIST_MEANS(double)
LIST_MEANS(float)
#undef X
#undef MAKE_PROCESS
+#undef C
#define X(ID, NAME, ...) [ID] = process_lf_##NAME,
static const process_func process_functions_lf[] = { LIST_MEANS() };
@@ -101,6 +110,9 @@ main(int argc, char *argv[])
enum method method = ARITHMETIC;
ARGBEGIN {
+ case 'd':
+ method = STANDARD_DEVIATION;
+ break;
case 'g':
method = GEOMETRIC;
break;
@@ -109,11 +121,11 @@ main(int argc, char *argv[])
break;
case 'l':
method = LEHMER;
- power = etolf_flag('l', UARGF());
+ power_file = UARGF();
break;
case 'p':
method = POWER;
- power = etolf_flag('p', UARGF());
+ power_file = UARGF();
break;
case 'v':
method = VARIANCE;
@@ -126,13 +138,19 @@ main(int argc, char *argv[])
usage();
eopen_stream(&stream, NULL);
+ if (power_file != NULL) {
+ eopen_stream(&power, power_file);
+ if (power.width != 1 || power.height != 1)
+ eprintf("%s: videos do not have the 1x1 geometry\n", power_file);
+ if (strcmp(power.pixfmt, stream.pixfmt))
+ eprintf("videos use incompatible pixel formats\n");
+ }
if (stream.encoding == DOUBLE)
process = process_functions_lf[method];
else
process = process_functions_f[method];
-
if (DPRINTF_HEAD(STDOUT_FILENO, stream.frames, 1, 1, stream.pixfmt) < 0)
eprintf("dprintf:");
process(&stream);
diff --git a/src/blind-temporal-mean.c b/src/blind-temporal-mean.c
@@ -1,7 +1,7 @@
/* See LICENSE file for copyright and license details. */
#include "common.h"
-USAGE("[-g | -h | -l power | -p power | -v]")
+USAGE("[-d | -g | -h | -l power-stream | -p power-stream | -v]")
/* TODO add [-w weight-stream] for [-ghlpv] */
/* Because the syntax for a function returning a function pointer is disgusting. */
@@ -19,24 +19,26 @@ typedef void (*process_func)(struct stream *stream, void *buffer, void *image, s
*/
#define LIST_MEANS(TYPE)\
/* [default] arithmetic mean */\
- X(ARITHMETIC, arithmetic, 1, COPY_FRAME,, *img1 += *buf,\
- a = (TYPE)1 / (TYPE)frame, *img1 *= a)\
+ X(ARITHMETIC, arithmetic, 1, COPY_FRAME,, *img += *buf,\
+ a = (TYPE)1 / (TYPE)frame, *img *= a)\
+ /* standard deviation */\
+ X(STANDARD_DEVIATION, sd, 2, ZERO_AND_PROCESS_FRAME,, (*img += *buf * *buf, *aux += *buf),\
+ a = (TYPE)1 / (TYPE)frame, *img = nnpow((*img - *aux * *aux * a) * a, (TYPE)0.5))\
/* geometric mean */\
- X(GEOMETRIC, geometric, 1, COPY_FRAME,, *img1 *= *buf,\
- a = (TYPE)1 / (TYPE)frame, *img1 = nnpow(*img1, a))\
+ X(GEOMETRIC, geometric, 1, COPY_FRAME,, *img *= *buf,\
+ a = (TYPE)1 / (TYPE)frame, *img = nnpow(*img, a))\
/* harmonic mean */\
- X(HARMONIC, harmonic, 1, ZERO_AND_PROCESS_FRAME,, *img1 += (TYPE)1 / *buf,\
- a = (TYPE)frame, *img1 = a / *img1)\
+ X(HARMONIC, harmonic, 1, ZERO_AND_PROCESS_FRAME,, *img += (TYPE)1 / *buf,\
+ a = (TYPE)frame, *img = a / *img)\
/* Lehmer mean */\
- X(LEHMER, lehmer, 2, ZERO_AND_PROCESS_FRAME, (a = (TYPE)power, b = a - (TYPE)1),\
- (*img1 += nnpow(*buf, a), *img2 += nnpow(*buf, b)),, *img1 /= *img2)\
+ X(LEHMER, lehmer, 2, ZERO_AND_PROCESS_FRAME,,\
+ (*img += nnpow(*buf, *pows), *aux += nnpow(*buf, *pows - (TYPE)1)),, *img /= *aux)\
/* power mean (Hölder mean) (m = 2 for root square mean; m = 3 for cubic mean) */\
- X(POWER, power, 1, ZERO_AND_PROCESS_FRAME, a = (TYPE)power,\
- *img1 += nnpow(*buf, a), (a = (TYPE)1 / (TYPE)frame, b = (TYPE)(1. / power)), \
- *img1 = a * nnpow(*img1, b))\
+ X(POWER, power, 1, ZERO_AND_PROCESS_FRAME,, *img += nnpow(*buf, *pows),\
+ a = (TYPE)1 / (TYPE)frame, *img = a * nnpow(*img, (TYPE)1 / *pows))\
/* variance */\
- X(VARIANCE, variance, 2, ZERO_AND_PROCESS_FRAME,, (*img1 += *buf * *buf, *img2 += *buf),\
- a = (TYPE)1 / (TYPE)frame, *img1 = (*img1 - *img2 * *img2 * a) * a)
+ X(VARIANCE, variance, 2, ZERO_AND_PROCESS_FRAME,, (*img += *buf * *buf, *aux += *buf),\
+ a = (TYPE)1 / (TYPE)frame, *img = (*img - *aux * *aux * a) * a)
enum first_frame_action {
COPY_FRAME,
@@ -48,31 +50,31 @@ enum first_frame_action {
enum method { LIST_MEANS() };
#undef X
-static double power;
+static void *powerbuf = NULL;
#define MAKE_PROCESS(PIXFMT, TYPE,\
_1, NAME, _3, _4, PRE_PROCESS, PROCESS_SUBCELL, PRE_FINALISE, FINALISE_SUBCELL)\
static void\
process_##PIXFMT##_##NAME(struct stream *stream, void *buffer, void *image, size_t frame)\
{\
- TYPE *buf = buffer, *img1 = image, a, b;\
- TYPE *img2 = (TYPE *)(((char *)image) + stream->frame_size);\
+ TYPE *buf = buffer, *img = image, a, *pows = powerbuf;\
+ TYPE *aux = (TYPE *)(((char *)image) + stream->frame_size);\
size_t x, y, z;\
if (!buf) {\
PRE_FINALISE;\
for (z = 0; z < stream->n_chan; z++)\
for (y = 0; y < stream->height; y++)\
- for (x = 0; x < stream->width; x++, img1++, img2++)\
+ for (x = 0; x < stream->width; x++, img++, aux++, pows++)\
FINALISE_SUBCELL;\
} else {\
PRE_PROCESS;\
for (z = 0; z < stream->n_chan; z++)\
for (y = 0; y < stream->height; y++)\
- for (x = 0; x < stream->width; x++, img1++, img2++, buf++) {\
+ for (x = 0; x < stream->width; x++, img++, aux++, pows++, buf++) { \
PROCESS_SUBCELL;\
}\
}\
- (void) img2, (void) a, (void) b, (void) frame;\
+ (void) aux, (void) a, (void) pows, (void) frame;\
}
#define X(...) MAKE_PROCESS(lf, double, __VA_ARGS__)
LIST_MEANS(double)
@@ -93,14 +95,18 @@ static const process_func process_functions_f[] = { LIST_MEANS() };
int
main(int argc, char *argv[])
{
- struct stream stream;
+ struct stream stream, power;
void *buf, *img;
process_func process;
size_t frames, images;
enum method method = ARITHMETIC;
enum first_frame_action first_frame_action;
+ const char *power_file = NULL;
ARGBEGIN {
+ case 'd':
+ method = STANDARD_DEVIATION;
+ break;
case 'g':
method = GEOMETRIC;
break;
@@ -109,11 +115,11 @@ main(int argc, char *argv[])
break;
case 'l':
method = LEHMER;
- power = etolf_flag('l', UARGF());
+ power_file = UARGF();
break;
case 'p':
method = POWER;
- power = etolf_flag('p', UARGF());
+ power_file = UARGF();
break;
case 'v':
method = VARIANCE;
@@ -138,6 +144,13 @@ main(int argc, char *argv[])
#undef X
eopen_stream(&stream, NULL);
+ if (power_file != NULL) {
+ eopen_stream(&power, power_file);
+ echeck_compat(&stream, &power);
+ powerbuf = emalloc(power.frame_size);
+ if (!eread_frame(&power, powerbuf))
+ eprintf("%s is no frames\n", power_file);
+ }
if (stream.encoding == DOUBLE)
process = process_functions_lf[method];
@@ -169,5 +182,6 @@ main(int argc, char *argv[])
ewriteall(STDOUT_FILENO, img, stream.frame_size, "<stdout>");
free(buf);
free(img);
+ free(powerbuf);
return 0;
}