aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO11
-rw-r--r--man/blind-colour-matrix.14
-rw-r--r--man/blind-convert.1102
-rw-r--r--man/blind-coordinate-field.14
-rw-r--r--man/blind-from-video.126
-rw-r--r--man/blind-rectangle-tessellation.14
-rw-r--r--man/blind-repeat.18
-rw-r--r--man/blind-single-colour.14
-rw-r--r--man/blind-triangle-tessellation.14
-rw-r--r--src/blind-affine-colour.c4
-rw-r--r--src/blind-apply-kernel.c2
-rw-r--r--src/blind-apply-palette.c1
-rw-r--r--src/blind-arithm.c7
-rw-r--r--src/blind-chroma-key.c2
-rw-r--r--src/blind-colour-matrix.c6
-rw-r--r--src/blind-cone-gradient.c1
-rw-r--r--src/blind-coordinate-field.c2
-rw-r--r--src/blind-cross-product.c3
-rw-r--r--src/blind-dissolve.c12
-rw-r--r--src/blind-dual-key.c3
-rw-r--r--src/blind-extract-alpha.c4
-rw-r--r--src/blind-find-rectangle.c7
-rw-r--r--src/blind-from-portable.c46
-rw-r--r--src/blind-from-text.c1
-rw-r--r--src/blind-from-video.c33
-rw-r--r--src/blind-gauss-blur.c2
-rw-r--r--src/blind-hexagon-tessellation.c5
-rw-r--r--src/blind-invert-luma.c30
-rw-r--r--src/blind-invert-matrix.c7
-rw-r--r--src/blind-linear-gradient.c1
-rw-r--r--src/blind-matrix-orthoproject.c1
-rw-r--r--src/blind-matrix-reflect.c1
-rw-r--r--src/blind-matrix-rotate.c1
-rw-r--r--src/blind-matrix-scale.c1
-rw-r--r--src/blind-matrix-shear.c1
-rw-r--r--src/blind-matrix-translate.c1
-rw-r--r--src/blind-matrix-transpose.c1
-rw-r--r--src/blind-mean.c5
-rw-r--r--src/blind-mosaic-corners.c4
-rw-r--r--src/blind-mosaic-edges.c4
-rw-r--r--src/blind-mosaic.c4
-rw-r--r--src/blind-multiply-matrices.c1
-rw-r--r--src/blind-norm.c3
-rw-r--r--src/blind-premultiply.c3
-rw-r--r--src/blind-quaternion-product.c3
-rw-r--r--src/blind-radial-gradient.c1
-rw-r--r--src/blind-rectangle-tessellation.c5
-rw-r--r--src/blind-repeat.c11
-rw-r--r--src/blind-set-alpha.c30
-rw-r--r--src/blind-set-luma.c3
-rw-r--r--src/blind-set-saturation.c18
-rw-r--r--src/blind-sinc-wave.c2
-rw-r--r--src/blind-single-colour.c3
-rw-r--r--src/blind-spatial-arithm.c5
-rw-r--r--src/blind-spatial-mean.c5
-rw-r--r--src/blind-spectrum.c2
-rw-r--r--src/blind-spiral-gradient.c1
-rw-r--r--src/blind-split-chans.c2
-rw-r--r--src/blind-square-gradient.c1
-rw-r--r--src/blind-stack.c18
-rw-r--r--src/blind-temporal-arithm.c4
-rw-r--r--src/blind-temporal-mean.c4
-rw-r--r--src/blind-time-blur.c5
-rw-r--r--src/blind-to-portable.c52
-rw-r--r--src/blind-to-text.c5
-rw-r--r--src/blind-to-video.c10
-rw-r--r--src/blind-transition.c6
-rw-r--r--src/blind-triangle-tessellation.c5
-rw-r--r--src/blind-unpremultiply.c3
-rw-r--r--src/blind-vector-projection.c3
-rw-r--r--src/common.h85
-rw-r--r--src/define-functions.h126
-rw-r--r--src/generate-macros.c32
-rw-r--r--src/stream.c181
-rw-r--r--src/stream.h26
-rw-r--r--src/util/endian.h25
76 files changed, 892 insertions, 167 deletions
diff --git a/TODO b/TODO
index 5dcb7d1..f27fde4 100644
--- a/TODO
+++ b/TODO
@@ -34,17 +34,10 @@ blind-preview a graphical tool for previewing the output of a pipeline
should display the output for a selected frame or image
should have sliders to tune environment variables
-blind-from-video: add options to:
- * just run ffmpeg just print the output
- * convert output from the option above to blind's format,
- but stop after a selected number of frames
- * like above, but instead of convert, simply read and
- print to stdout (up to user to direct to /dev/null
- for discarding)
-
blind-cone-gradient: add ability to make gradient superelliptic
+blind-to-text, blind-from-text: support %a, %e, %g, and custom precision
-Add [-j jobs] to blind-from-video, blind-to-video, and blind-apply-kernel.
+Add [-j jobs] to blind-from-video, blind-to-video, blind-convert, and blind-apply-kernel.
long double is slightly faster than long.
long double (xyza q) could be added as another format.
diff --git a/man/blind-colour-matrix.1 b/man/blind-colour-matrix.1
index a976260..05ed44a 100644
--- a/man/blind-colour-matrix.1
+++ b/man/blind-colour-matrix.1
@@ -55,7 +55,9 @@ CIE Standard Illuminant D65 is used.
.BR -F " "\fIpixel-format\fP
Select pixel format, see
.BR blind-convert (1)
-for more information.
+for more information. Pixel formats starting with
+.BR raw
+are not supported.
.TP
.B -z
Parse arguments as CIE XYY instead of CIE XYZ.
diff --git a/man/blind-convert.1 b/man/blind-convert.1
index dd87b78..500ebaa 100644
--- a/man/blind-convert.1
+++ b/man/blind-convert.1
@@ -40,6 +40,108 @@ The same colour space as the input stream, but with
each subpixel value is stored as a double-precision
floating-point number using the local machines
endianness.
+.TP
+.B raw0
+Use output from
+.BR ffmpeg (1)
+as-is, that is little-endian, 16-bit integer AY'UV.
+.TP
+.B raw1
+Little-endian, 16-bit integer Y'UVA.
+.TP
+.B raw2
+Host-endian, 16-bit integer Y'UV.
+.TP
+.B raw2a
+Host-endian, 16-bit integer Y'UVA.
+.TP
+.B raw3 f
+Host-endian, single-precision float-point Y'UV.
+.TP
+.B raw3 !f
+Host-endian, double-precision float-point Y'UV.
+.TP
+.B raw3
+Host-endian, double-precision float-point Y'UV,
+but single-precision float-point if input is
+single-precision float-point.
+.TP
+.B raw3a f
+Host-endian, single-precision float-point Y'UVA.
+.TP
+.B raw3a !f
+Host-endian, double-precision float-point Y'UVA.
+.TP
+.B raw3a
+Host-endian, double-precision float-point Y'UVA,
+but single-precision float-point if input is
+single-precision float-point.
+.TP
+.B raw4 f
+Host-endian, single-precision float-point XY'Z.
+.TP
+.B raw4 !f
+Host-endian, double-precision float-point XY'Z.
+.TP
+.B raw4
+Host-endian, double-precision float-point XY'Z,
+but single-precision float-point if input is
+single-precision float-point.
+.TP
+.B raw4a f
+Host-endian, single-precision float-point XY'ZA.
+.TP
+.B raw4a !f
+Host-endian, double-precision float-point XY'ZA.
+.TP
+.B raw4a
+Host-endian, double-precision float-point XY'ZA,
+but single-precision float-point if input is
+single-precision float-point.
+.TP
+.B raw5 f
+Host-endian, single-precision float-point sR'G'B'.
+.TP
+.B raw5 !f
+Host-endian, double-precision float-point sR'G'B'.
+.TP
+.B raw5
+Host-endian, double-precision float-point sR'G'B',
+but single-precision float-point if input is
+single-precision float-point.
+.TP
+.B raw5a f
+Host-endian, single-precision float-point sR'G'B'A.
+.TP
+.B raw5a !f
+Host-endian, double-precision float-point sR'G'B'A.
+.TP
+.B raw5a
+Host-endian, double-precision float-point sR'G'B'A,
+but single-precision float-point if input is
+single-precision float-point.
+.TP
+.B raw6 f
+Host-endian, single-precision float-point sRGB.
+.TP
+.B raw6 !f
+Host-endian, double-precision float-point sRGB.
+.TP
+.B raw6
+Host-endian, double-precision float-point sRGB,
+but single-precision float-point if input is
+single-precision float-point.
+.TP
+.B raw6a f
+Host-endian, single-precision float-point sRGBA.
+.TP
+.B raw6a !f
+Host-endian, double-precision float-point sRGBA.
+.TP
+.B raw6a
+Host-endian, double-precision float-point sRGBA,
+but single-precision float-point if input is
+single-precision float-point.
.SH SEE ALSO
.BR blind (7)
.SH AUTHORS
diff --git a/man/blind-coordinate-field.1 b/man/blind-coordinate-field.1
index 371cfec..fe5e0fb 100644
--- a/man/blind-coordinate-field.1
+++ b/man/blind-coordinate-field.1
@@ -36,7 +36,9 @@ no processes with an open read end to this process's stdout.
.BR -F " "\fIpixel-format\fP
Select pixel format, see
.BR blind-convert (1)
-for more information.
+for more information. Pixel formats starting with
+.BR raw
+are not supported.
.TP
.BR -w " "\fIwidth\fP
The width of the video, in pixels.
diff --git a/man/blind-from-video.1 b/man/blind-from-video.1
index 9172af2..68e355b 100644
--- a/man/blind-from-video.1
+++ b/man/blind-from-video.1
@@ -13,7 +13,7 @@ blind-from-video - Converts a regular, cooked video to a blind video
.IR height ]
[-dL]
.I input-file
-.I output-file
+.RI [ output-file ]
.SH DESCRIPTION
.B blind-from-video
converts the video, in the file
@@ -34,6 +34,12 @@ It is unspecified what happens if
.I input-file
does not have exactly one video stream. All non-video streams,
such as audio and subtitles are discarded.
+.P
+If
+.B output-file
+is omitted,
+.RB ' - '
+(stdout) is used.
.SH OPTIONS
.TP
.B -d
@@ -44,11 +50,26 @@ drafting or if you will not modify the colours. If you use this
flag, you should also use it in
.BR blind-to-video (1),
otherwise the colours will be modified.
+
+This is similar to
+.B -F raw
+and piping the output to
+.BR blind-convert (1)
+with
+.BR "-F raw4" ,
+however, the
+.B xyza
+is recorded instead of
+.BR raw4 .
.TP
.BR -F " "\fIpixel-format\fP
Select pixel format, see
.BR blind-convert (1)
-for more information.
+for more information. Pixel formats starting with
+.BR raw ,
+other than
+.BR raw0 ,
+are not supported.
.TP
.BR -h " "\fIheight\fP
Change the height of the video to
@@ -84,6 +105,7 @@ Change the width of the video to
.SH SEE ALSO
.BR blind (7),
.BR blind-to-video (1),
+.BR blind-convert (1),
.BR blind-split (1),
.BR blind-rewrite-head (1)
.SH AUTHORS
diff --git a/man/blind-rectangle-tessellation.1 b/man/blind-rectangle-tessellation.1
index 6bcd4c0..75876dc 100644
--- a/man/blind-rectangle-tessellation.1
+++ b/man/blind-rectangle-tessellation.1
@@ -23,7 +23,9 @@ pixels tall.
.BR -F " "\fIpixel-format\fP
Select pixel format, see
.BR blind-convert (1)
-for more information.
+for more information. Pixel formats starting with
+.BR raw
+are not supported.
.SH SEE ALSO
.BR blind (7),
.BR blind-hexagon-tessellation (1),
diff --git a/man/blind-repeat.1 b/man/blind-repeat.1
index bbd54b6..f9005af 100644
--- a/man/blind-repeat.1
+++ b/man/blind-repeat.1
@@ -7,7 +7,7 @@ blind-repeat - Repeat a video
.I count
|
.RB ' inf ')
-.I file
+.RI [ file ]
.SH DESCRIPTION
.B blind-repeat
write the a video to stdout that is a loop of the
@@ -34,6 +34,12 @@ will read stdin into memory; you are highly discouraged
from using this unless stdin is a single frame, or known
to only be a very small number of frames, is it can
potentially use all of the computer's memory.
+.P
+If
+.I file
+is omitted,
+.RB ' - '
+is used.
.SH OPTIONS
.TP
.B -f
diff --git a/man/blind-single-colour.1 b/man/blind-single-colour.1
index 2e3d675..4fc72ac 100644
--- a/man/blind-single-colour.1
+++ b/man/blind-single-colour.1
@@ -55,7 +55,9 @@ no processes with an open read end to this process's stdout.
.BR -F " "\fIpixel-format\fP
Select pixel format, see
.BR blind-convert (1)
-for more information.
+for more information. Pixel formats starting with
+.BR raw
+are not supported.
.TP
.BR -w " "\fIwidth\fP
The width of the video, in pixels.
diff --git a/man/blind-triangle-tessellation.1 b/man/blind-triangle-tessellation.1
index ed0b9a9..6ba58bc 100644
--- a/man/blind-triangle-tessellation.1
+++ b/man/blind-triangle-tessellation.1
@@ -26,7 +26,9 @@ go from northwest to southeast.
.BR -F " "\fIpixel-format\fP
Select pixel format, see
.BR blind-convert (1)
-for more information.
+for more information. Pixel formats starting with
+.BR raw
+are not supported.
.SH SEE ALSO
.BR blind (7),
.BR blind-hexagon-tessellation (1),
diff --git a/src/blind-affine-colour.c b/src/blind-affine-colour.c
index 654345f..f7bda25 100644
--- a/src/blind-affine-colour.c
+++ b/src/blind-affine-colour.c
@@ -40,6 +40,10 @@ main(int argc, char *argv[])
eopen_stream(&matrix, argv[0]);
SELECT_PROCESS_FUNCTION(&colour);
+ if (skip_alpha && colour.alpha_chan != -1)
+ CHECK_CHANS(&colour, == colour.n_chan - 1, == colour.luma_chan);
+ else
+ skip_alpha = 0;
if (strcmp(colour.pixfmt, matrix.pixfmt))
eprintf("videos use incompatible pixel formats\n");
diff --git a/src/blind-apply-kernel.c b/src/blind-apply-kernel.c
index 6c00ab7..04a816d 100644
--- a/src/blind-apply-kernel.c
+++ b/src/blind-apply-kernel.c
@@ -49,6 +49,8 @@ main(int argc, char *argv[])
eopen_stream(&kernel, argv[0]);
SELECT_PROCESS_FUNCTION(&colour);
+ CHECK_ALPHA_CHAN(&colour);
+ CHECK_N_CHAN(&colour, 4, 4);
if (colour.encoding != kernel.encoding || colour.n_chan != kernel.n_chan)
eprintf("videos use incompatible pixel formats");
if (per_pixel && !(kernel.width % colour.width || kernel.height % colour.height))
diff --git a/src/blind-apply-palette.c b/src/blind-apply-palette.c
index ad5fb4b..6b26736 100644
--- a/src/blind-apply-palette.c
+++ b/src/blind-apply-palette.c
@@ -35,6 +35,7 @@ main(int argc, char *argv[])
eopen_stream(&palette, argv[0]);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_N_CHAN(&stream, 4, 4);
if (strcmp(stream.pixfmt, palette.pixfmt))
eprintf("videos use incompatible pixel formats\n");
diff --git a/src/blind-arithm.c b/src/blind-arithm.c
index 4c6ca14..c5d3947 100644
--- a/src/blind-arithm.c
+++ b/src/blind-arithm.c
@@ -105,10 +105,15 @@ main(int argc, char *argv[])
frames = streams[i].frames;
}
+ if (streams->alpha)
+ CHECK_ALPHA(streams);
+ CHECK_N_CHAN(streams, 1, 3 + !!streams->alpha);
if (streams->encoding == DOUBLE)
process = get_process_lf(operation);
- else
+ else if (streams->encoding == FLOAT)
process = get_process_f(operation);
+ else
+ eprintf("pixel format %s is not supported, try xyza\n", streams->pixfmt);
tmp = streams->frames, streams->frames = frames;
fprint_stream_head(stdout, streams);
diff --git a/src/blind-chroma-key.c b/src/blind-chroma-key.c
index e9e8bcb..222facd 100644
--- a/src/blind-chroma-key.c
+++ b/src/blind-chroma-key.c
@@ -19,6 +19,8 @@ main(int argc, char *argv[])
eopen_stream(&key, argv[0]);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_ALPHA_CHAN(&stream);
+ CHECK_N_CHAN(&stream, 4, 4);
if (strcmp(stream.pixfmt, key.pixfmt))
eprintf("videos use incompatible pixel formats\n");
diff --git a/src/blind-colour-matrix.c b/src/blind-colour-matrix.c
index 7387beb..01d3f27 100644
--- a/src/blind-colour-matrix.c
+++ b/src/blind-colour-matrix.c
@@ -124,12 +124,16 @@ main(int argc, char *argv[])
}
}
+ CHECK_ALPHA_CHAN(&stream);
+ CHECK_COLOUR_SPACE(&stream, CIEXYZ);
if (stream.encoding == DOUBLE) {
ewriteall(STDOUT_FILENO, Mlf, sizeof(Mlf), "<stdout>");
- } else {
+ } else if (stream.encoding == FLOAT) {
for (i = 0; i < ELEMENTSOF(Mlf); i++)
Mf[i] = (float)Mlf[i];
ewriteall(STDOUT_FILENO, Mf, sizeof(Mf), "<stdout>");
+ } else {
+ eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
}
return 0;
diff --git a/src/blind-cone-gradient.c b/src/blind-cone-gradient.c
index 095c56e..e1b7241 100644
--- a/src/blind-cone-gradient.c
+++ b/src/blind-cone-gradient.c
@@ -42,6 +42,7 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_N_CHAN(&stream, 4, 4);
if (stream.width > 3 || stream.height > 3 ||
stream.width * stream.height < 2 ||
diff --git a/src/blind-coordinate-field.c b/src/blind-coordinate-field.c
index 3b8a7c6..1c87876 100644
--- a/src/blind-coordinate-field.c
+++ b/src/blind-coordinate-field.c
@@ -46,6 +46,8 @@ main(int argc, char *argv[])
eset_pixel_format(&stream, pixfmt);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_N_CHAN(&stream, 4, 4);
+
fprint_stream_head(stdout, &stream);
efflush(stdout, "<stdout>");
process();
diff --git a/src/blind-cross-product.c b/src/blind-cross-product.c
index 910b49b..4d38cf4 100644
--- a/src/blind-cross-product.c
+++ b/src/blind-cross-product.c
@@ -19,6 +19,9 @@ main(int argc, char *argv[])
eopen_stream(&right, argv[0]);
SELECT_PROCESS_FUNCTION(&left);
+ CHECK_ALPHA_CHAN(&left);
+ CHECK_N_CHAN(&left, 4, 4);
+
fprint_stream_head(stdout, &left);
efflush(stdout, "<stdout>");
process_two_streams(&left, &right, STDOUT_FILENO, "<stdout>", process);
diff --git a/src/blind-dissolve.c b/src/blind-dissolve.c
index be92c2e..b78121e 100644
--- a/src/blind-dissolve.c
+++ b/src/blind-dissolve.c
@@ -10,10 +10,10 @@ static int reverse = 0;
#define PROCESS(TYPE)\
do {\
- size_t i;\
+ size_t i = stream->alpha_chan * stream->chan_size;\
TYPE a = fm ? (TYPE)(reverse ? f : fm - f) / fm_##TYPE : (TYPE)0.5;\
- for (i = 0; i < n; i += stream->pixel_size)\
- ((TYPE *)(stream->buf + i))[3] *= a;\
+ for (; i < n; i += stream->pixel_size)\
+ *(TYPE *)(stream->buf + i) *= a;\
} while (0)
static void process_lf(struct stream *stream, size_t n, size_t f) {PROCESS(double);}
@@ -38,10 +38,8 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
- if (stream.encoding == DOUBLE)
- process = process_lf;
- else
- process = process_f;
+ SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_CHANS(&stream, != -1, == stream.luma_chan);
if (!stream.frames)
eprintf("video's length is not recorded");
diff --git a/src/blind-dual-key.c b/src/blind-dual-key.c
index 6fa3348..8feb6bf 100644
--- a/src/blind-dual-key.c
+++ b/src/blind-dual-key.c
@@ -29,6 +29,9 @@ main(int argc, char *argv[])
eopen_stream(&dual, argv[6]);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_ALPHA_CHAN(&stream);
+ CHECK_N_CHAN(&stream, 4, 4);
+
fprint_stream_head(stdout, &stream);
efflush(stdout, "<stdout>");
process_two_streams(&stream, &dual, STDOUT_FILENO, "<stdout>", process);
diff --git a/src/blind-extract-alpha.c b/src/blind-extract-alpha.c
index 49b3947..3d74ece 100644
--- a/src/blind-extract-alpha.c
+++ b/src/blind-extract-alpha.c
@@ -20,6 +20,8 @@ main(int argc, char *argv[])
fd = eopen(argv[0], O_WRONLY | O_CREAT | O_TRUNC, 0666);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_CHANS(&stream, != -1, == stream.luma_chan);
+
fprint_stream_head(stdout, &stream);
efflush(stdout, "<stdout>");
if (dprint_stream_head(fd, &stream) < 0)
@@ -38,7 +40,7 @@ PROCESS(struct stream *stream, int fd, const char *fname)
TYPE a, *p, *b;
do {
n = stream->ptr / stream->pixel_size;
- p = (TYPE *)(stream->buf) + stream->n_chan - 1;
+ p = (TYPE *)(stream->buf) + stream->luma_chan;
b = (TYPE *)buf;
for (i = 0; i < n; i++, p += stream->n_chan) {
a = *p, *p = 1;
diff --git a/src/blind-find-rectangle.c b/src/blind-find-rectangle.c
index ac6e843..54cf2cc 100644
--- a/src/blind-find-rectangle.c
+++ b/src/blind-find-rectangle.c
@@ -111,18 +111,23 @@ main(int argc, char *argv[])
cache = emalloc2(stream.width + 1, sizeof(*cache));
buf = emalloc(stream.row_size);
+ if (argc > 3)
+ CHECK_ALPHA(&stream);
+ CHECK_N_CHAN(&stream, 1, 3 + !!stream.alpha);
if (stream.encoding == DOUBLE) {
colour_lf[0] = X;
colour_lf[1] = Y;
colour_lf[2] = Z;
colour_lf[3] = alpha;
process(colour_lf);
- } else {
+ } else if (stream.encoding == FLOAT) {
colour_f[0] = (float)X;
colour_f[1] = (float)Y;
colour_f[2] = (float)Z;
colour_f[3] = (float)alpha;
process(colour_f);
+ } else {
+ eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
}
fshut(stdout, "<stdout>");
diff --git a/src/blind-from-portable.c b/src/blind-from-portable.c
index c51e2db..e80510b 100644
--- a/src/blind-from-portable.c
+++ b/src/blind-from-portable.c
@@ -1,4 +1,5 @@
/* See LICENSE file for copyright and license details. */
+#define INCLUDE_UINT16
#include "common.h"
USAGE("[-s]")
@@ -47,7 +48,7 @@ static int strict = 1;
return ret;\
} while (0)
-#define PROCESS(ITYPE, OTYPE, BITS)\
+#define PROCESS_FLOAT(ITYPE, OTYPE, BITS)\
do {\
size_t i, n;\
ITYPE *ibuf = (ITYPE *)(stream->buf);\
@@ -55,15 +56,19 @@ static int strict = 1;
: alloca(sizeof(stream->buf) / sizeof(ITYPE) * sizeof(OTYPE));\
strict *= !USING_BINARY##BITS;\
if (!strict && sizeof(ITYPE) != sizeof(OTYPE))\
- eprintf("-s is required on this machine\n");\
+ eprintf("-s is supported not on this machine\n");\
+ if (stream->endian == HOST_ENDIAN && !strict) {\
+ esend_stream(stream, STDOUT_FILENO, "<stdout>");\
+ break;\
+ }\
do {\
n = stream->ptr / sizeof(ITYPE);\
if (strict) {\
for (i = 0; i < n; i++)\
- obuf[i] = conv_##OTYPE(le##BITS##toh(ibuf[i]));\
+ obuf[i] = conv_##OTYPE(letoh(ibuf[i]));\
} else {\
for (i = 0; i < n; i++)\
- obuf[i] = *(OTYPE *)&(ITYPE){le##BITS##toh(ibuf[i])};\
+ obuf[i] = *(OTYPE *)&(ITYPE){letoh(ibuf[i])};\
}\
ewriteall(STDOUT_FILENO, obuf, n * sizeof(OTYPE), "<stdout>");\
n *= sizeof(ITYPE);\
@@ -73,11 +78,32 @@ static int strict = 1;
eprintf("%s: incomplete frame\n", stream->file);\
} while (0)
+#define PROCESS_INTEGER(TYPE)\
+ do {\
+ size_t i, n;\
+ TYPE *buf = (TYPE *)(stream->buf);\
+ if (stream->endian == HOST_ENDIAN) {\
+ esend_stream(stream, STDOUT_FILENO, "<stdout>");\
+ break;\
+ }\
+ do {\
+ n = stream->ptr / sizeof(TYPE);\
+ for (i = 0; i < n; i++)\
+ buf[i] = letoh(buf[i]);\
+ n *= sizeof(TYPE);\
+ 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);\
+ } while (0)
+
static double conv_double(uint64_t portable) {CONV(uint64_t, int64_t, double, 11, 1023, 52);}
static float conv_float (uint32_t portable) {CONV(uint32_t, int32_t, float, 8, 127, 23);}
-static void process_lf(struct stream *stream) {PROCESS(uint64_t, double, 64);}
-static void process_f (struct stream *stream) {PROCESS(uint32_t, float, 32);}
+static void process_lf (struct stream *stream) {PROCESS_FLOAT(uint64_t, double, 64);}
+static void process_f (struct stream *stream) {PROCESS_FLOAT(uint32_t, float, 32);}
+static void process_u16(struct stream *stream) {PROCESS_INTEGER(uint16_t);}
int
main(int argc, char *argv[])
@@ -97,9 +123,15 @@ main(int argc, char *argv[])
usage();
eopen_stream(&stream, NULL);
+#if defined(HOST_ENDIAN_IS_LITTLE_ENDIAN)
+ if (stream.endian == LITTLE_ENDIAN)
+ stream.endian = HOST_ENDIAN;
+#elif defined(HOST_ENDIAN_IS_BIG_ENDIAN)
+ if (stream.endian == BIG_ENDIAN)
+ stream.endian = HOST_ENDIAN;
+#endif
SELECT_PROCESS_FUNCTION(&stream);
-
fprint_stream_head(stdout, &stream);
efflush(stdout, "<stdout>");
process(&stream);
diff --git a/src/blind-from-text.c b/src/blind-from-text.c
index 2832a9a..328fd23 100644
--- a/src/blind-from-text.c
+++ b/src/blind-from-text.c
@@ -1,5 +1,6 @@
/* See LICENSE file for copyright and license details. */
#ifndef TYPE
+#define INCLUDE_UINT16
#include "common.h"
USAGE("")
diff --git a/src/blind-from-video.c b/src/blind-from-video.c
index 07f4bda..8f53af2 100644
--- a/src/blind-from-video.c
+++ b/src/blind-from-video.c
@@ -1,7 +1,7 @@
/* See LICENSE file for copyright and license details. */
#include "common.h"
-USAGE("[-F pixel-format] [-r frame-rate] [-w width -h height] [-dL] input-file output-file")
+USAGE("[-F pixel-format] [-r frame-rate] [-w width -h height] [-dL] input-file [output-file]")
static int draft = 0;
static void (*convert_segment)(char *buf, size_t n, int fd, const char *file);
@@ -153,16 +153,21 @@ convert(const char *infile, int outfd, const char *outfile, size_t width, size_t
close(pipe_rw[1]);
- for (ptr = 0;;) {
- if (!(n = eread(pipe_rw[0], buf + ptr, sizeof(buf) - ptr, "<subprocess>")))
- break;
- ptr += n;
- n = ptr - (ptr % 8);
- convert_segment(buf, n, outfd, outfile);
- memmove(buf, buf + n, ptr -= n);
+ if (convert_segment) {
+ for (ptr = 0;;) {
+ if (!(n = eread(pipe_rw[0], buf + ptr, sizeof(buf) - ptr, "<subprocess>")))
+ break;
+ ptr += n;
+ n = ptr - (ptr % 8);
+ convert_segment(buf, n, outfd, outfile);
+ memmove(buf, buf + n, ptr -= n);
+ }
+ if (ptr)
+ eprintf("<subprocess>: incomplete frame\n");
+ } else {
+ while ((n = eread(pipe_rw[0], buf, sizeof(buf), "<subprocess>")))
+ ewriteall(outfd, buf, (size_t)n, outfile);
}
- if (ptr)
- eprintf("<subprocess>: incomplete frame\n");
close(pipe_rw[0]);
ewaitpid(pid, &status, 0);
@@ -208,19 +213,21 @@ main(int argc, char *argv[])
usage();
} ARGEND;
- if (argc != 2 || !width != !height)
+ if (argc < 1 || argc > 2 || !width != !height)
usage();
infile = argv[0];
- outfile = argv[1];
+ outfile = argv[1] ? argv[1] : "-";
pixfmt = get_pixel_format(pixfmt, "xyza");
if (!strcmp(pixfmt, "xyza"))
convert_segment = convert_segment_xyza;
else if (!strcmp(pixfmt, "xyza f"))
convert_segment = convert_segment_xyzaf;
+ else if (!strcmp(pixfmt, "raw0"))
+ convert_segment = NULL;
else
- eprintf("pixel format %s is not supported, try xyza\n", pixfmt);
+ eprintf("pixel format %s is not supported, try xyza or raw0 and blind-convert\n", pixfmt);
if (!width)
get_metadata(infile, &width, &height);
diff --git a/src/blind-gauss-blur.c b/src/blind-gauss-blur.c
index 53eaecb..e22fd2e 100644
--- a/src/blind-gauss-blur.c
+++ b/src/blind-gauss-blur.c
@@ -361,6 +361,8 @@ main(int argc, char *argv[])
eopen_stream(&sigma, argv[0]);
SELECT_PROCESS_FUNCTION(&colour);
+ CHECK_CHANS(&colour, == 3, == (measure_y_only ? 1 : colour.luma_chan));
+ CHECK_N_CHAN(&colour, 4, 4);
echeck_compat(&colour, &sigma);
diff --git a/src/blind-hexagon-tessellation.c b/src/blind-hexagon-tessellation.c
index abb5c7a..377c110 100644
--- a/src/blind-hexagon-tessellation.c
+++ b/src/blind-hexagon-tessellation.c
@@ -47,10 +47,13 @@ main(int argc, char *argv[])
diameter = etozu_arg("block-diameter", argv[0], 1, SIZE_MAX);
eset_pixel_format(&stream, pixfmt);
+ CHECK_N_CHAN(&stream, 4, 4);
if (stream.encoding == DOUBLE)
SET_XYZA(double);
- else
+ else if (stream.encoding == FLOAT)
SET_XYZA(float);
+ else
+ eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
stream.width = (size_t)((double)diameter * sqrt(3.));
stream.height = diameter * 3 / 2;
diff --git a/src/blind-invert-luma.c b/src/blind-invert-luma.c
index d26f081..e6b8a34 100644
--- a/src/blind-invert-luma.c
+++ b/src/blind-invert-luma.c
@@ -41,14 +41,14 @@ USAGE("[-iw] mask-stream")
}\
} while (0)
-static void process_xyza (struct stream *colour, struct stream *mask, size_t n) {PROCESS(double,);}
-static void process_xyza_i (struct stream *colour, struct stream *mask, size_t n) {PROCESS(double, 1 -);}
-static void process_xyza_w (struct stream *colour, struct stream *mask, size_t n) {PROCESS_W(double,);}
-static void process_xyza_iw (struct stream *colour, struct stream *mask, size_t n) {PROCESS_W(double, 1 -);}
-static void process_xyzaf (struct stream *colour, struct stream *mask, size_t n) {PROCESS(float,);}
-static void process_xyzaf_i (struct stream *colour, struct stream *mask, size_t n) {PROCESS(float, 1 -);}
-static void process_xyzaf_w (struct stream *colour, struct stream *mask, size_t n) {PROCESS_W(float,);}
-static void process_xyzaf_iw(struct stream *colour, struct stream *mask, size_t n) {PROCESS_W(float, 1 -);}
+static void process_lf (struct stream *colour, struct stream *mask, size_t n) {PROCESS(double,);}
+static void process_lf_i (struct stream *colour, struct stream *mask, size_t n) {PROCESS(double, 1 -);}
+static void process_lf_w (struct stream *colour, struct stream *mask, size_t n) {PROCESS_W(double,);}
+static void process_lf_iw(struct stream *colour, struct stream *mask, size_t n) {PROCESS_W(double, 1 -);}
+static void process_f (struct stream *colour, struct stream *mask, size_t n) {PROCESS(float,);}
+static void process_f_i (struct stream *colour, struct stream *mask, size_t n) {PROCESS(float, 1 -);}
+static void process_f_w (struct stream *colour, struct stream *mask, size_t n) {PROCESS_W(float,);}
+static void process_f_iw (struct stream *colour, struct stream *mask, size_t n) {PROCESS_W(float, 1 -);}
int
main(int argc, char *argv[])
@@ -74,12 +74,14 @@ main(int argc, char *argv[])
eopen_stream(&colour, NULL);
eopen_stream(&mask, argv[0]);
- if (!strcmp(colour.pixfmt, "xyza"))
- process = invert ? whitepoint ? process_xyza_iw : process_xyza_i
- : whitepoint ? process_xyza_w : process_xyza;
- else if (!strcmp(colour.pixfmt, "xyza f"))
- process = invert ? whitepoint ? process_xyzaf_iw : process_xyzaf_i
- : whitepoint ? process_xyzaf_w : process_xyzaf;
+ CHECK_ALPHA(&colour);
+ CHECK_COLOUR_SPACE(&colour, CIEXYZ);
+ if (colour.encoding == DOUBLE)
+ process = invert ? whitepoint ? process_lf_iw : process_lf_i
+ : whitepoint ? process_lf_w : process_lf;
+ else if (colour.encoding == FLOAT)
+ process = invert ? whitepoint ? process_f_iw : process_f_i
+ : whitepoint ? process_f_w : process_f;
else
eprintf("pixel format %s is not supported, try xyza\n", colour.pixfmt);
diff --git a/src/blind-invert-matrix.c b/src/blind-invert-matrix.c
index 66b1176..5be63c4 100644
--- a/src/blind-invert-matrix.c
+++ b/src/blind-invert-matrix.c
@@ -58,11 +58,14 @@ main(int argc, char *argv[])
stream.width = width;
efflush(stdout, "<stdout>");
+ if (skip_ch[3] && stream.alpha_chan != -1)
+ CHECK_ALPHA_CHAN(&stream);
+ CHECK_N_CHAN(&stream, 1, 4);
one = alloca(stream.pixel_size);
- if (!strcmp(stream.pixfmt, "xyza")) {
+ if (stream.encoding == DOUBLE) {
*(double *)one = 1;
process = process_lf;
- } else if (!strcmp(stream.pixfmt, "xyza f")) {
+ } else if (stream.encoding == FLOAT) {
*(float *)one = 1;
process = process_f;
} else {
diff --git a/src/blind-linear-gradient.c b/src/blind-linear-gradient.c
index 55711ac..d8e3cf7 100644
--- a/src/blind-linear-gradient.c
+++ b/src/blind-linear-gradient.c
@@ -37,6 +37,7 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_N_CHAN(&stream, 4, 4);
if (stream.width > 2 || stream.height > 2 || stream.width * stream.height != 2)
eprintf("<stdin>: each frame must contain exactly 2 pixels\n");
diff --git a/src/blind-matrix-orthoproject.c b/src/blind-matrix-orthoproject.c
index 816e76c..f3f70c4 100644
--- a/src/blind-matrix-orthoproject.c
+++ b/src/blind-matrix-orthoproject.c
@@ -29,6 +29,7 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_CHANS(&stream, == 3, == 1);
if (stream.width > 2 || stream.height > 2 || stream.width * stream.height != 2)
eprintf("<stdin>: each frame must contain exactly 2 pixels\n");
diff --git a/src/blind-matrix-reflect.c b/src/blind-matrix-reflect.c
index 5dcf89e..2a20cdd 100644
--- a/src/blind-matrix-reflect.c
+++ b/src/blind-matrix-reflect.c
@@ -29,6 +29,7 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_CHANS(&stream, == 3, == 1);
if (stream.width > 2 || stream.height > 2 || stream.width * stream.height != 2)
eprintf("<stdin>: each frame must contain exactly 2 pixels\n");
diff --git a/src/blind-matrix-rotate.c b/src/blind-matrix-rotate.c
index 945205d..946fb3c 100644
--- a/src/blind-matrix-rotate.c
+++ b/src/blind-matrix-rotate.c
@@ -33,6 +33,7 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_CHANS(&stream, == 3, == 1);
if (stream.width != 1 || stream.height != 1)
eprintf("<stdin>: each frame must contain exactly 1 pixels\n");
diff --git a/src/blind-matrix-scale.c b/src/blind-matrix-scale.c
index 15f27cc..c03f3e2 100644
--- a/src/blind-matrix-scale.c
+++ b/src/blind-matrix-scale.c
@@ -29,6 +29,7 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_CHANS(&stream, == 3, == 1);
if (stream.width > 2 || stream.height > 2 || stream.width * stream.height != 2)
eprintf("<stdin>: each frame must contain exactly 2 pixels\n");
diff --git a/src/blind-matrix-shear.c b/src/blind-matrix-shear.c
index 8130cba..55b2b1c 100644
--- a/src/blind-matrix-shear.c
+++ b/src/blind-matrix-shear.c
@@ -37,6 +37,7 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_CHANS(&stream, == 3, == 1);
if (stream.width > 2 || stream.height > 2 || stream.width * stream.height != 2)
eprintf("<stdin>: each frame must contain exactly 2 pixels\n");
diff --git a/src/blind-matrix-translate.c b/src/blind-matrix-translate.c
index 5ae1104..e53f386 100644
--- a/src/blind-matrix-translate.c
+++ b/src/blind-matrix-translate.c
@@ -29,6 +29,7 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_CHANS(&stream, == 3, == 1);
if (stream.width > 2 || stream.height > 2 || stream.width * stream.height != 2)
eprintf("<stdin>: each frame must contain exactly 2 pixels\n");
diff --git a/src/blind-matrix-transpose.c b/src/blind-matrix-transpose.c
index 3f19053..8ebb2a0 100644
--- a/src/blind-matrix-transpose.c
+++ b/src/blind-matrix-transpose.c
@@ -29,6 +29,7 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_CHANS(&stream, == 3, == 1);
if (stream.width != 1 || stream.height != 1)
eprintf("<stdin>: each frame must contain exactly 1 pixels\n");
diff --git a/src/blind-mean.c b/src/blind-mean.c
index 8b7e97c..d7c0726 100644
--- a/src/blind-mean.c
+++ b/src/blind-mean.c
@@ -109,7 +109,6 @@ main(int argc, char *argv[])
enum method method = ARITHMETIC;
int i, two = 0;
-
ARGBEGIN {
case 'd':
method = STANDARD_DEVIATION;
@@ -171,8 +170,10 @@ main(int argc, char *argv[])
if (streams->encoding == DOUBLE)
process = process_functions_lf[method];
- else
+ else if (streams->encoding == FLOAT)
process = process_functions_f[method];
+ else
+ eprintf("pixel format %s is not supported, try xyza\n", streams->pixfmt);
tmp = streams->frames, streams->frames = frames;
fprint_stream_head(stdout, streams);
diff --git a/src/blind-mosaic-corners.c b/src/blind-mosaic-corners.c
index ecb9692..83c33bf 100644
--- a/src/blind-mosaic-corners.c
+++ b/src/blind-mosaic-corners.c
@@ -59,12 +59,12 @@ main(int argc, char *argv[])
colours[1] = alloca(stream.pixel_size);
memset(colours[0], 0, stream.pixel_size);
- if (!strcmp(stream.pixfmt, "xyza")) {
+ if (stream.encoding == DOUBLE) {
((double *)(colours[1]))[0] = (double)1;
((double *)(colours[1]))[1] = (double)1;
((double *)(colours[1]))[2] = (double)1;
((double *)(colours[1]))[3] = (double)1;
- } else if (!strcmp(stream.pixfmt, "xyza f")) {
+ } else if (stream.encoding == FLOAT) {
((float *)(colours[1]))[0] = (float)1;
((float *)(colours[1]))[1] = (float)1;
((float *)(colours[1]))[2] = (float)1;
diff --git a/src/blind-mosaic-edges.c b/src/blind-mosaic-edges.c
index b59dbda..4f05052 100644
--- a/src/blind-mosaic-edges.c
+++ b/src/blind-mosaic-edges.c
@@ -39,12 +39,12 @@ main(int argc, char *argv[])
colours[1] = alloca(stream.pixel_size);
memset(colours[0], 0, stream.pixel_size);
- if (!strcmp(stream.pixfmt, "xyza")) {
+ if (stream.encoding == DOUBLE) {
((double *)(colours[1]))[0] = (double)1;
((double *)(colours[1]))[1] = (double)1;
((double *)(colours[1]))[2] = (double)1;
((double *)(colours[1]))[3] = (double)1;
- } else if (!strcmp(stream.pixfmt, "xyza f")) {
+ } else if (stream.encoding == FLOAT) {
((float *)(colours[1]))[0] = (float)1;
((float *)(colours[1]))[1] = (float)1;
((float *)(colours[1]))[2] = (float)1;
diff --git a/src/blind-mosaic.c b/src/blind-mosaic.c
index a0f36da..3cf40a2 100644
--- a/src/blind-mosaic.c
+++ b/src/blind-mosaic.c
@@ -158,8 +158,10 @@ main(int argc, char *argv[])
eopen_stream(&mosaic, argv[0]);
SELECT_PROCESS_FUNCTION(&colour);
- echeck_compat(&colour, &mosaic);
+ CHECK_ALPHA(&colour);
+ CHECK_N_CHAN(&colour, 4, 4);
+ echeck_compat(&colour, &mosaic);
fprint_stream_head(stdout, &colour);
efflush(stdout, "<stdout>");
process_each_frame_two_streams(&colour, &mosaic, STDOUT_FILENO, "<stdout>", process);
diff --git a/src/blind-multiply-matrices.c b/src/blind-multiply-matrices.c
index af86311..d99b22a 100644
--- a/src/blind-multiply-matrices.c
+++ b/src/blind-multiply-matrices.c
@@ -67,6 +67,7 @@ main(int argc, char *argv[])
}
SELECT_PROCESS_FUNCTION(streams);
+ CHECK_N_CHAN(streams, 1, 4);
w = streams->width, streams->width = max_width;
h = streams->height, streams->height = max_height;
diff --git a/src/blind-norm.c b/src/blind-norm.c
index 303c214..25830c4 100644
--- a/src/blind-norm.c
+++ b/src/blind-norm.c
@@ -41,6 +41,9 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_ALPHA_CHAN(&stream);
+ CHECK_N_CHAN(&stream, 4, 4);
+
fprint_stream_head(stdout, &stream);
efflush(stdout, "<stdout>");
process(&stream);
diff --git a/src/blind-premultiply.c b/src/blind-premultiply.c
index c670b60..31135ff 100644
--- a/src/blind-premultiply.c
+++ b/src/blind-premultiply.c
@@ -37,6 +37,9 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_CHANS(&stream, == 3, == stream.luma_chan);
+ CHECK_N_CHAN(&stream, 4, 4);
+
fprint_stream_head(stdout, &stream);
efflush(stdout, "<stdout>");
process(&stream);
diff --git a/src/blind-quaternion-product.c b/src/blind-quaternion-product.c
index 06a2887..2c3bbe9 100644
--- a/src/blind-quaternion-product.c
+++ b/src/blind-quaternion-product.c
@@ -19,6 +19,9 @@ main(int argc, char *argv[])
eopen_stream(&right, argv[0]);
SELECT_PROCESS_FUNCTION(&left);
+ CHECK_ALPHA_CHAN(&left);
+ CHECK_N_CHAN(&left, 4, 4);
+
fprint_stream_head(stdout, &left);
efflush(stdout, "<stdout>");
process_two_streams(&left, &right, STDOUT_FILENO, "<stdout>", process);
diff --git a/src/blind-radial-gradient.c b/src/blind-radial-gradient.c
index a97e474..e2e940f 100644
--- a/src/blind-radial-gradient.c
+++ b/src/blind-radial-gradient.c
@@ -34,6 +34,7 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_N_CHAN(&stream, 4, 4);
if (stream.width > 3 || stream.height > 3 ||
stream.width * stream.height < 2 ||
diff --git a/src/blind-rectangle-tessellation.c b/src/blind-rectangle-tessellation.c
index 2d83222..7ffcb49 100644
--- a/src/blind-rectangle-tessellation.c
+++ b/src/blind-rectangle-tessellation.c
@@ -47,10 +47,13 @@ main(int argc, char *argv[])
height = etozu_arg("block-height", argv[1], 1, SIZE_MAX);
eset_pixel_format(&stream, pixfmt);
+ CHECK_N_CHAN(&stream, 4, 4);
if (stream.encoding == DOUBLE)
SET_XYZA(double);
- else
+ else if (stream.encoding == FLOAT)
SET_XYZA(float);
+ else
+ eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
stream.width = 2 * width;
stream.height = 2 * height;
diff --git a/src/blind-repeat.c b/src/blind-repeat.c
index e56586d..80ce883 100644
--- a/src/blind-repeat.c
+++ b/src/blind-repeat.c
@@ -1,7 +1,7 @@
/* See LICENSE file for copyright and license details. */
#include "common.h"
-USAGE("([-f] count | 'inf') file")
+USAGE("([-f] count | 'inf') [file]")
static size_t count = 0;
static int inf;
@@ -76,7 +76,7 @@ main(int argc, char *argv[])
usage();
} ARGEND;
- if (argc != 2)
+ if (argc < 1 || argc > 2)
usage();
if ((inf = !strcmp(argv[0], "inf"))) {
@@ -87,14 +87,17 @@ main(int argc, char *argv[])
count = etozu_arg("the count", argv[0], 0, SIZE_MAX);
}
- eopen_stream(&stream, !strcmp(argv[1], "-") ? NULL : argv[1]);
+ if (argv[1] && !strcmp(argv[1], "-"))
+ argv[1] = NULL;
+
+ eopen_stream(&stream, argv[1]);
if (stream.frames && count > SIZE_MAX / stream.frames)
eprintf("%s: video is too long\n", stream.file);
stream.frames *= count;
fprint_stream_head(stdout, &stream);
efflush(stdout, "<stdout>");
- if (!strcmp(argv[1], "-")
+ if (!argv[1]
? (framewise ? repeat_stdin_framewise() : repeat_stdin())
: (framewise ? repeat_regular_file_framewise(): repeat_regular_file()))
if (!inf || errno != EPIPE)
diff --git a/src/blind-set-alpha.c b/src/blind-set-alpha.c
index c548673..31c4df4 100644
--- a/src/blind-set-alpha.c
+++ b/src/blind-set-alpha.c
@@ -6,18 +6,18 @@ USAGE("[-i] alpha-stream")
#define PROCESS(TYPE, INV)\
do {\
size_t i;\
- TYPE a;\
- for (i = 0; i < n; i += colour->pixel_size) {\
- a = INV ((TYPE *)(alpha->buf + i))[1];\
- a *= ((TYPE *)(alpha->buf + i))[3];\
- ((TYPE *)(colour->buf + i))[3] *= a;\
- }\
+ TYPE *luma = (TYPE *)(alpha->buf) + alpha->luma_chan;\
+ TYPE *alph = (TYPE *)(alpha->buf) + alpha->alpha_chan;\
+ TYPE *out = (TYPE *)(colour->buf) + colour->alpha_chan;\
+ n /= colour->chan_size;\
+ for (i = 0; i < n; i += colour->n_chan)\
+ out[i] *= (INV luma[i]) * alph[i];\
} while (0)
-static void process_xyza (struct stream *colour, struct stream *alpha, size_t n) {PROCESS(double,);}
-static void process_xyza_i (struct stream *colour, struct stream *alpha, size_t n) {PROCESS(double, 1 -);}
-static void process_xyzaf (struct stream *colour, struct stream *alpha, size_t n) {PROCESS(float,);}
-static void process_xyzaf_i(struct stream *colour, struct stream *alpha, size_t n) {PROCESS(float, 1 -);}
+static void process_lf (struct stream *colour, struct stream *alpha, size_t n) {PROCESS(double,);}
+static void process_lf_i(struct stream *colour, struct stream *alpha, size_t n) {PROCESS(double, 1 -);}
+static void process_f (struct stream *colour, struct stream *alpha, size_t n) {PROCESS(float,);}
+static void process_f_i (struct stream *colour, struct stream *alpha, size_t n) {PROCESS(float, 1 -);}
int
main(int argc, char *argv[])
@@ -40,10 +40,12 @@ main(int argc, char *argv[])
eopen_stream(&colour, NULL);
eopen_stream(&alpha, argv[0]);
- if (!strcmp(colour.pixfmt, "xyza"))
- process = invert ? process_xyza_i : process_xyza;
- else if (!strcmp(colour.pixfmt, "xyza f"))
- process = invert ? process_xyzaf_i : process_xyzaf;
+ CHECK_CHANS(&colour, != -1, != -1);
+ CHECK_ALPHA(&colour);
+ if (colour.encoding == DOUBLE)
+ process = invert ? process_lf_i : process_lf;
+ else if (colour.encoding == FLOAT)
+ process = invert ? process_f_i : process_f;
else
eprintf("pixel format %s is not supported, try xyza\n", colour.pixfmt);
diff --git a/src/blind-set-luma.c b/src/blind-set-luma.c
index 2943982..66bf52f 100644
--- a/src/blind-set-luma.c
+++ b/src/blind-set-luma.c
@@ -19,6 +19,9 @@ main(int argc, char *argv[])
eopen_stream(&luma, argv[0]);
SELECT_PROCESS_FUNCTION(&colour);
+ CHECK_CHANS(&colour, == 3, == 1);
+ CHECK_COLOUR_SPACE(&colour, CIEXYZ);
+
fprint_stream_head(stdout, &colour);
efflush(stdout, "<stdout>");
process_two_streams(&colour, &luma, STDOUT_FILENO, "<stdout>", process);
diff --git a/src/blind-set-saturation.c b/src/blind-set-saturation.c
index 2c30377..c7e6ebf 100644
--- a/src/blind-set-saturation.c
+++ b/src/blind-set-saturation.c
@@ -41,10 +41,10 @@ USAGE("[-w] saturation-stream")
}\
} while (0)
-static void process_xyza (struct stream *colour, struct stream *satur, size_t n) {PROCESS(double);}
-static void process_xyza_w (struct stream *colour, struct stream *satur, size_t n) {PROCESS_W(double);}
-static void process_xyzaf (struct stream *colour, struct stream *satur, size_t n) {PROCESS(float);}
-static void process_xyzaf_w(struct stream *colour, struct stream *satur, size_t n) {PROCESS_W(float);}
+static void process_lf (struct stream *colour, struct stream *satur, size_t n) {PROCESS(double);}
+static void process_lf_w(struct stream *colour, struct stream *satur, size_t n) {PROCESS_W(double);}
+static void process_f (struct stream *colour, struct stream *satur, size_t n) {PROCESS(float);}
+static void process_f_w (struct stream *colour, struct stream *satur, size_t n) {PROCESS_W(float);}
int
main(int argc, char *argv[])
@@ -67,10 +67,12 @@ main(int argc, char *argv[])
eopen_stream(&colour, NULL);
eopen_stream(&satur, argv[0]);
- if (!strcmp(colour.pixfmt, "xyza"))
- process = whitepoint ? process_xyza_w : process_xyza;
- else if (!strcmp(colour.pixfmt, "xyza f"))
- process = whitepoint ? process_xyzaf_w : process_xyzaf;
+ CHECK_COLOUR_SPACE(&colour, CIEXYZ);
+ CHECK_CHANS(&colour, == 3, == 1);
+ if (colour.encoding == DOUBLE)
+ process = whitepoint ? process_lf_w : process_lf;
+ else if (colour.encoding == FLOAT)
+ process = whitepoint ? process_f_w : process_f;
else
eprintf("pixel format %s is not supported, try xyza\n", colour.pixfmt);
diff --git a/src/blind-sinc-wave.c b/src/blind-sinc-wave.c
index 0f999c5..0cda31e 100644
--- a/src/blind-sinc-wave.c
+++ b/src/blind-sinc-wave.c
@@ -35,6 +35,8 @@ main(int argc, char *argv[])
}
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_CHANS(&stream, == 3, == 1);
+ CHECK_N_CHAN(&stream, 4, 4);
if (have_theta0 && strcmp(stream.pixfmt, theta0.pixfmt))
eprintf("videos use incompatible pixel formats\n");
diff --git a/src/blind-single-colour.c b/src/blind-single-colour.c
index 7e8c348..567a7f5 100644
--- a/src/blind-single-colour.c
+++ b/src/blind-single-colour.c
@@ -59,6 +59,9 @@ main(int argc, char *argv[])
eset_pixel_format(&stream, pixfmt);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_N_CHAN(&stream, 4, 4);
+ if (argc < 3)
+ CHECK_COLOUR_SPACE(&stream, CIEXYZ);
fprint_stream_head(stdout, &stream);
efflush(stdout, "<stdout>");
diff --git a/src/blind-spatial-arithm.c b/src/blind-spatial-arithm.c
index b63dc89..898a15b 100644
--- a/src/blind-spatial-arithm.c
+++ b/src/blind-spatial-arithm.c
@@ -80,10 +80,13 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
+ CHECK_N_CHAN(&stream, 4, 4);
if (stream.encoding == DOUBLE)
process = get_process_lf(argv[0]);
- else
+ else if (stream.encoding == FLOAT)
process = get_process_f(argv[0]);
+ else
+ eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
if (DPRINTF_HEAD(STDOUT_FILENO, stream.frames, 1, 1, stream.pixfmt) < 0)
eprintf("dprintf:");
diff --git a/src/blind-spatial-mean.c b/src/blind-spatial-mean.c
index 5511a3f..ab7f2ce 100644
--- a/src/blind-spatial-mean.c
+++ b/src/blind-spatial-mean.c
@@ -146,10 +146,13 @@ main(int argc, char *argv[])
eprintf("videos use incompatible pixel formats\n");
}
+ CHECK_N_CHAN(&stream, 4, 4);
if (stream.encoding == DOUBLE)
process = process_functions_lf[method];
- else
+ else if (stream.encoding == FLOAT)
process = process_functions_f[method];
+ else
+ eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
if (DPRINTF_HEAD(STDOUT_FILENO, stream.frames, 1, 1, stream.pixfmt) < 0)
eprintf("dprintf:");
diff --git a/src/blind-spectrum.c b/src/blind-spectrum.c
index 3ba6191..92763aa 100644
--- a/src/blind-spectrum.c
+++ b/src/blind-spectrum.c
@@ -34,6 +34,8 @@ main(int argc, char *argv[])
eopen_stream(&spectrum, argv[0]);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_CHANS(&stream, == 3, == (luma ? 1 : stream.luma_chan));
+ CHECK_N_CHAN(&stream, 4, 4);
if (stream.n_chan != spectrum.n_chan || stream.encoding != spectrum.encoding)
eprintf("videos use incompatible pixel formats\n");
diff --git a/src/blind-spiral-gradient.c b/src/blind-spiral-gradient.c
index 6ea0601..478b8c8 100644
--- a/src/blind-spiral-gradient.c
+++ b/src/blind-spiral-gradient.c
@@ -53,6 +53,7 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_N_CHAN(&stream, 4, 4);
if (stream.width > 5 || stream.height > 5 ||
stream.width * stream.height < 2 ||
diff --git a/src/blind-split-chans.c b/src/blind-split-chans.c
index 305fe98..b475521 100644
--- a/src/blind-split-chans.c
+++ b/src/blind-split-chans.c
@@ -24,6 +24,8 @@ main(int argc, char *argv[])
usage();
eopen_stream(&stream, NULL);
+ CHECK_ALPHA_CHAN(&stream);
+ CHECK_N_CHAN(&stream, 4, 4);
xfd = eopen(argv[0], O_WRONLY | O_CREAT | O_TRUNC, 0666);
yfd = eopen(argv[1], O_WRONLY | O_CREAT | O_TRUNC, 0666);
diff --git a/src/blind-square-gradient.c b/src/blind-square-gradient.c
index 3a754a2..8032476 100644
--- a/src/blind-square-gradient.c
+++ b/src/blind-square-gradient.c
@@ -34,6 +34,7 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_N_CHAN(&stream, 4, 4);
if (stream.width > 3 || stream.height > 3 ||
stream.width * stream.height < 2 ||
diff --git a/src/blind-stack.c b/src/blind-stack.c
index 29e20b0..c922015 100644
--- a/src/blind-stack.c
+++ b/src/blind-stack.c
@@ -33,10 +33,10 @@ USAGE("[-bs] bottom-stream ... top-stream")
}\
} while (0)
-static void process_xyza (struct stream *streams, size_t n_streams, size_t n) { PROCESS(double, 0); }
-static void process_xyza_b (struct stream *streams, size_t n_streams, size_t n) { PROCESS(double, 1); }
-static void process_xyzaf (struct stream *streams, size_t n_streams, size_t n) { PROCESS(float, 0); }
-static void process_xyzaf_b(struct stream *streams, size_t n_streams, size_t n) { PROCESS(float, 1); }
+static void process_lf (struct stream *streams, size_t n_streams, size_t n) { PROCESS(double, 0); }
+static void process_lf_b(struct stream *streams, size_t n_streams, size_t n) { PROCESS(double, 1); }
+static void process_f (struct stream *streams, size_t n_streams, size_t n) { PROCESS(float, 0); }
+static void process_f_b (struct stream *streams, size_t n_streams, size_t n) { PROCESS(float, 1); }
int
main(int argc, char *argv[])
@@ -72,12 +72,14 @@ main(int argc, char *argv[])
frames = streams[i].frames;
}
- if (!strcmp(streams->pixfmt, "xyza"))
- process = blend ? process_xyza_b : process_xyza;
- else if (!strcmp(streams->pixfmt, "xyza f"))
- process = blend ? process_xyzaf_b : process_xyzaf;
+ if (streams->encoding == DOUBLE)
+ process = blend ? process_lf_b :process_lf;
+ else if (streams->encoding == FLOAT)
+ process = blend ? process_f_b : process_f;
else
eprintf("pixel format %s is not supported, try xyza\n", streams->pixfmt);
+ CHECK_ALPHA_CHAN(streams);
+ CHECK_N_CHAN(streams, 4, 4);
tmp = streams->frames, streams->frames = frames;
fprint_stream_head(stdout, streams);
diff --git a/src/blind-temporal-arithm.c b/src/blind-temporal-arithm.c
index f9f7b51..7b447e6 100644
--- a/src/blind-temporal-arithm.c
+++ b/src/blind-temporal-arithm.c
@@ -73,8 +73,10 @@ main(int argc, char *argv[])
if (stream.encoding == DOUBLE)
process = get_process_lf(argv[0]);
- else
+ else if (stream.encoding == FLOAT)
process = get_process_f(argv[0]);
+ else
+ eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
img = emalloc(stream.frame_size);
diff --git a/src/blind-temporal-mean.c b/src/blind-temporal-mean.c
index 4633d75..8a72a27 100644
--- a/src/blind-temporal-mean.c
+++ b/src/blind-temporal-mean.c
@@ -154,8 +154,10 @@ main(int argc, char *argv[])
if (stream.encoding == DOUBLE)
process = process_functions_lf[method];
- else
+ else if (stream.encoding == FLOAT)
process = process_functions_f[method];
+ else
+ eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
stream.frames = 1;
echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
diff --git a/src/blind-time-blur.c b/src/blind-time-blur.c
index 6827d26..666c299 100644
--- a/src/blind-time-blur.c
+++ b/src/blind-time-blur.c
@@ -28,6 +28,9 @@ main(int argc, char *argv[])
eopen_stream(&alpha, argv[0]);
SELECT_PROCESS_FUNCTION(&colour);
+ CHECK_CHANS(&colour, == 3, == 1);
+ CHECK_N_CHAN(&colour, 4, 4);
+
echeck_compat(&colour, &alpha);
fprint_stream_head(stdout, &colour);
efflush(stdout, "<stdout>");
@@ -45,7 +48,7 @@ PROCESS(char *output, char *restrict cbuf, char *restrict abuf,
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);
+ size_t i, n = colour->width * colour->height;
TYPE a1, a2;
if (first) {
diff --git a/src/blind-to-portable.c b/src/blind-to-portable.c
index 2d9c899..07eee62 100644
--- a/src/blind-to-portable.c
+++ b/src/blind-to-portable.c
@@ -1,4 +1,5 @@
/* See LICENSE file for copyright and license details. */
+#define INCLUDE_UINT16
#include "common.h"
/* Disable warnings in <math.h> */
@@ -9,6 +10,8 @@
USAGE("[-s]")
+static int strict = 1;
+
#define CONV(ITYPE, OTYPE, SOTYPE, EXPONENT, HA2EXPONENT, FRACTION)\
do {\
static int cache_i = 0;\
@@ -62,7 +65,7 @@ USAGE("[-s]")
return ret;\
} while (0)
-#define PROCESS(ITYPE, OTYPE, BITS)\
+#define PROCESS_FLOAT(ITYPE, OTYPE, BITS)\
do {\
size_t i, n;\
ITYPE *ibuf = (ITYPE *)(stream->buf);\
@@ -70,15 +73,19 @@ USAGE("[-s]")
: alloca(sizeof(stream->buf) / sizeof(ITYPE) * sizeof(OTYPE));\
strict *= !USING_BINARY##BITS;\
if (!strict && sizeof(ITYPE) != sizeof(OTYPE))\
- eprintf("-s is required on this machine\n");\
+ eprintf("-s is supported not on this machine\n");\
+ if (stream->endian == LITTLE_ENDIAN && !strict) {\
+ esend_stream(stream, STDOUT_FILENO, "<stdout>");\
+ break;\
+ }\
do {\
n = stream->ptr / sizeof(ITYPE);\
if (strict) {\
for (i = 0; i < n; i++)\
- obuf[i] = htole##BITS(conv_##ITYPE(ibuf[i]));\
+ obuf[i] = htole(conv_##ITYPE(ibuf[i]));\
} else {\
for (i = 0; i < n; i++)\
- obuf[i] = htole##BITS(*(OTYPE *)&ibuf[i]);\
+ obuf[i] = htole(*(OTYPE *)&ibuf[i]);\
}\
ewriteall(STDOUT_FILENO, obuf, n * sizeof(OTYPE), "<stdout>");\
n *= sizeof(ITYPE);\
@@ -88,18 +95,38 @@ USAGE("[-s]")
eprintf("%s: incomplete frame\n", stream->file);\
} while (0)
+#define PROCESS_INTEGER(TYPE)\
+ do {\
+ size_t i, n;\
+ TYPE *buf = (TYPE *)(stream->buf);\
+ if (stream->endian == LITTLE_ENDIAN) {\
+ esend_stream(stream, STDOUT_FILENO, "<stdout>");\
+ break;\
+ }\
+ do {\
+ n = stream->ptr / sizeof(TYPE);\
+ for (i = 0; i < n; i++)\
+ buf[i] = htole(buf[i]);\
+ n *= sizeof(TYPE);\
+ 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);\
+ } while (0)
+
static uint64_t conv_double(double host) {CONV(double, uint64_t, int64_t, 11, 1023, 52);}
static uint32_t conv_float (float host) {CONV(float, uint32_t, int32_t, 8, 127, 23);}
-static void process_lf(struct stream *stream, int strict) {PROCESS(double, uint64_t, 64);}
-static void process_f (struct stream *stream, int strict) {PROCESS(float, uint32_t, 32);}
+static void process_lf (struct stream *stream) {PROCESS_FLOAT(double, uint64_t, 64);}
+static void process_f (struct stream *stream) {PROCESS_FLOAT(float, uint32_t, 32);}
+static void process_u16(struct stream *stream) {PROCESS_INTEGER(uint16_t);}
int
main(int argc, char *argv[])
{
struct stream stream;
- int strict = 1;
- void (*process)(struct stream *stream, int strict);
+ void (*process)(struct stream *stream);
ARGBEGIN {
case 's':
@@ -113,10 +140,17 @@ main(int argc, char *argv[])
usage();
eopen_stream(&stream, NULL);
+#if defined(HOST_ENDIAN_IS_LITTLE_ENDIAN)
+ if (stream.endian == HOST_ENDIAN)
+ stream.endian = LITTLE_ENDIAN;
+#elif defined(HOST_ENDIAN_IS_BIG_ENDIAN)
+ if (stream.endian == HOST_ENDIAN)
+ stream.endian = BIG_ENDIAN;
+#endif
SELECT_PROCESS_FUNCTION(&stream);
fprint_stream_head(stdout, &stream);
efflush(stdout, "<stdout>");
- process(&stream, strict);
+ process(&stream);
return 0;
}
diff --git a/src/blind-to-text.c b/src/blind-to-text.c
index 61bd14d..befa3c7 100644
--- a/src/blind-to-text.c
+++ b/src/blind-to-text.c
@@ -1,5 +1,6 @@
/* See LICENSE file for copyright and license details. */
#ifndef TYPE
+#define INCLUDE_UINT16
#include "common.h"
USAGE("")
@@ -32,7 +33,11 @@ PROCESS(struct stream *stream, size_t n)
size_t i;
TYPE *p = (TYPE *)(stream->buf);
for (i = 0, n /= stream->chan_size; i < n; i++)
+#ifdef INTEGER_TYPE
+ printf("%"PRINT_TYPE"%c", (PRINT_CAST)(p[i]), (i + 1) % stream->n_chan ? ' ' : '\n');
+#else
printf("%.25"PRINT_TYPE"%c", (PRINT_CAST)(p[i]), (i + 1) % stream->n_chan ? ' ' : '\n');
+#endif
}
#endif
diff --git a/src/blind-to-video.c b/src/blind-to-video.c
index 1c9ef99..5cdffe6 100644
--- a/src/blind-to-video.c
+++ b/src/blind-to-video.c
@@ -51,8 +51,11 @@ main(int argc, char *argv[])
process = process_lf;
else if (!strcmp(stream.pixfmt, "xyza f"))
process = process_f;
+ else if (!strcmp(stream.pixfmt, "raw0"))
+ process = NULL;
else
- eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
+ eprintf("pixel format %s is not supported, try converting to "
+ "raw0 or xyza with blind-convert\n", stream.pixfmt);
epipe(pipe_rw);
pid = efork();
@@ -69,7 +72,10 @@ main(int argc, char *argv[])
close(pipe_rw[0]);
fd = pipe_rw[1];
- process_stream(&stream, process);
+ if (process)
+ process_stream(&stream, process);
+ else
+ esend_stream(&stream, fd, "<subprocess>");
close(fd);
ewaitpid(pid, &status, 0);
diff --git a/src/blind-transition.c b/src/blind-transition.c
index 8463575..758857a 100644
--- a/src/blind-transition.c
+++ b/src/blind-transition.c
@@ -81,10 +81,14 @@ main(int argc, char *argv[])
echeck_compat(&stream, &softness);
}
+ CHECK_ALPHA(&stream);
+ CHECK_COLOUR_SPACE(&stream, CIEXYZ);
if (stream.encoding == DOUBLE)
process = process_lf;
- else
+ else if (stream.encoding == FLOAT)
process = process_f;
+ else
+ eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
if (!stream.frames)
eprintf("video's length is not recorded");
diff --git a/src/blind-triangle-tessellation.c b/src/blind-triangle-tessellation.c
index 8d298f0..f806527 100644
--- a/src/blind-triangle-tessellation.c
+++ b/src/blind-triangle-tessellation.c
@@ -63,10 +63,13 @@ main(int argc, char *argv[])
height = etozu_arg("block-height", argv[1], 1, SIZE_MAX);
eset_pixel_format(&stream, pixfmt);
+ CHECK_N_CHAN(&stream, 4, 4);
if (stream.encoding == DOUBLE)
SET_XYZA(double);
- else
+ else if (stream.encoding == FLOAT)
SET_XYZA(float);
+ else
+ eprintf("pixel format %s is not supported, try xyza\n", stream.pixfmt);
stream.width = 2 * width;
stream.height = 2 * height;
diff --git a/src/blind-unpremultiply.c b/src/blind-unpremultiply.c
index d3feced..11d186c 100644
--- a/src/blind-unpremultiply.c
+++ b/src/blind-unpremultiply.c
@@ -37,6 +37,9 @@ main(int argc, char *argv[])
eopen_stream(&stream, NULL);
SELECT_PROCESS_FUNCTION(&stream);
+ CHECK_CHANS(&stream, == 3, == stream.luma_chan);
+ CHECK_N_CHAN(&stream, 4, 4);
+
fprint_stream_head(stdout, &stream);
efflush(stdout, "<stdout>");
process(&stream);
diff --git a/src/blind-vector-projection.c b/src/blind-vector-projection.c
index a285846..8d65738 100644
--- a/src/blind-vector-projection.c
+++ b/src/blind-vector-projection.c
@@ -37,6 +37,9 @@ main(int argc, char *argv[])
eopen_stream(&right, argv[0]);
SELECT_PROCESS_FUNCTION(&left);
+ CHECK_ALPHA_CHAN(&left);
+ CHECK_N_CHAN(&left, 4, 4);
+
fprint_stream_head(stdout, &left);
efflush(stdout, "<stdout>");
process_two_streams(&left, &right, STDOUT_FILENO, "<stdout>", process);
diff --git a/src/common.h b/src/common.h
index 7d253c0..3972389 100644
--- a/src/common.h
+++ b/src/common.h
@@ -69,10 +69,89 @@
# define PIPE_BUF BUFSIZ
#endif
+#ifndef DONT_INCLUDE_FLOAT
+# define SELECT_PROCESS_FUNCTION_FLOAT(stream) else if ((stream)->encoding == FLOAT) process = process_f
+#else
+# define SELECT_PROCESS_FUNCTION_FLOAT(stream) else if (0)
+#endif
+
+#ifndef DONT_INCLUDE_DOUBLE
+# define SELECT_PROCESS_FUNCTION_DOUBLE(stream) else if ((stream)->encoding == DOUBLE) process = process_lf
+#else
+# define SELECT_PROCESS_FUNCTION_DOUBLE(stream) else if (0)
+#endif
+
+#ifdef INCLUDE_LONG_DOUBLE
+# define SELECT_PROCESS_FUNCTION_LONG_DOUBLE(stream) else if ((stream)->encoding == LONG_DOUBLE) process = process_llf
+#else
+# define SELECT_PROCESS_FUNCTION_LONG_DOUBLE(stream) else if (0)
+#endif
+
+#ifdef INCLUDE_UINT8
+# define SELECT_PROCESS_FUNCTION_UINT8(stream) else if ((stream)->encoding == UINT8) process = process_u8
+#else
+# define SELECT_PROCESS_FUNCTION_UINT8(stream) else if (0)
+#endif
+
+#ifdef INCLUDE_UINT16
+# define SELECT_PROCESS_FUNCTION_UINT16(stream) else if ((stream)->encoding == UINT16) process = process_u16
+#else
+# define SELECT_PROCESS_FUNCTION_UINT16(stream) else if (0)
+#endif
+
+#ifdef INCLUDE_UINT32
+# define SELECT_PROCESS_FUNCTION_UINT32(stream) else if ((stream)->encoding == UINT32) process = process_u32
+#else
+# define SELECT_PROCESS_FUNCTION_UINT32(stream) else if (0)
+#endif
+
+#ifdef INCLUDE_UINT64
+# define SELECT_PROCESS_FUNCTION_UINT64(stream) else if ((stream)->encoding == UINT64) process = process_u64
+#else
+# define SELECT_PROCESS_FUNCTION_UINT64(stream) else if (0)
+#endif
+
#define SELECT_PROCESS_FUNCTION(stream)\
do {\
- if ((stream)->encoding == DOUBLE)\
- process = process_lf;\
+ if ((stream)->endian != HOST_ENDIAN)\
+ eprintf("pixel format %s is not supported, try xyza\n", (stream)->pixfmt);\
+ SELECT_PROCESS_FUNCTION_FLOAT(stream);\
+ SELECT_PROCESS_FUNCTION_DOUBLE(stream);\
+ SELECT_PROCESS_FUNCTION_LONG_DOUBLE(stream);\
+ SELECT_PROCESS_FUNCTION_UINT8(stream);\
+ SELECT_PROCESS_FUNCTION_UINT16(stream);\
+ SELECT_PROCESS_FUNCTION_UINT32(stream);\
+ SELECT_PROCESS_FUNCTION_UINT64(stream);\
else\
- process = process_f;\
+ eprintf("pixel format %s is not supported, try xyza\n", (stream)->pixfmt);\
+ } while (0)
+
+#define CHECK_ALPHA_CHAN(stream)\
+ do {\
+ if ((stream)->alpha_chan != 3)\
+ eprintf("pixel format %s is not supported, try xyza\n", (stream)->pixfmt);\
+ } while (0)
+
+#define CHECK_CHANS(stream, ALPHA, LUMA)\
+ do {\
+ if (!(((stream)->alpha_chan ALPHA) && ((stream)->luma_chan LUMA)))\
+ eprintf("pixel format %s is not supported, try xyza\n", (stream)->pixfmt);\
+ } while (0)
+
+#define CHECK_ALPHA(stream)\
+ do {\
+ if ((stream)->alpha != UNPREMULTIPLIED)\
+ eprintf("pixel format %s is not supported, try xyza\n", (stream)->pixfmt);\
+ } while (0)
+
+#define CHECK_COLOUR_SPACE(stream, colour_space)\
+ do {\
+ if ((stream)->space != (colour_space))\
+ eprintf("pixel format %s is not supported, try xyza\n", (stream)->pixfmt);\
+ } while (0)
+
+#define CHECK_N_CHAN(stream, low, high)\
+ do {\
+ if ((stream)->n_chan < (low) || (stream)->n_chan > (high))\
+ eprintf("pixel format %s is not supported, try xyza\n", (stream)->pixfmt);\
} while (0)
diff --git a/src/define-functions.h b/src/define-functions.h
index 3a44829..029265e 100644
--- a/src/define-functions.h
+++ b/src/define-functions.h
@@ -1,25 +1,107 @@
/* See LICENSE file for copyright and license details. */
-#define PROCESS process_lf
-#define TYPE double
-#define SCAN_TYPE "lf"
-#define PRINT_TYPE "lf"
-#define PRINT_CAST double
-#include FILE
-#undef PROCESS
-#undef TYPE
-#undef SCAN_TYPE
-#undef PRINT_TYPE
-#undef PRINT_CAST
+#ifndef DONT_INCLUDE_FLOAT
+# define PROCESS process_lf
+# define TYPE double
+# define SCAN_TYPE "lf"
+# define PRINT_TYPE "lf"
+# define PRINT_CAST double
+# include FILE
+# undef PROCESS
+# undef TYPE
+# undef SCAN_TYPE
+# undef PRINT_TYPE
+# undef PRINT_CAST
+#endif
-#define PROCESS process_f
-#define TYPE float
-#define SCAN_TYPE "f"
-#define PRINT_TYPE "lf"
-#define PRINT_CAST double
-#include FILE
-#undef PROCESS
-#undef TYPE
-#undef SCAN_TYPE
-#undef PRINT_TYPE
-#undef PRINT_CAST
+#ifndef DONT_INCLUDE_DOUBLE
+# define PROCESS process_f
+# define TYPE float
+# define SCAN_TYPE "f"
+# define PRINT_TYPE "lf"
+# define PRINT_CAST double
+# include FILE
+# undef PROCESS
+# undef TYPE
+# undef SCAN_TYPE
+# undef PRINT_TYPE
+# undef PRINT_CAST
+#endif
+
+#ifdef INCLUDE_DOUBLE_LONG
+# define PROCESS process_llf
+# define TYPE long double
+# define SCAN_TYPE "Lf"
+# define PRINT_TYPE "Lf"
+# define PRINT_CAST long double
+# include FILE
+# undef PROCESS
+# undef TYPE
+# undef SCAN_TYPE
+# undef PRINT_TYPE
+# undef PRINT_CAST
+#endif
+
+#ifdef INCLUDE_UINT8
+# define PROCESS process_u8
+# define TYPE uint8_t
+# define SCAN_TYPE SCNu8
+# define PRINT_TYPE "u"
+# define PRINT_CAST unsigned
+# define INTEGER_TYPE
+# include FILE
+# undef PROCESS
+# undef TYPE
+# undef SCAN_TYPE
+# undef PRINT_TYPE
+# undef PRINT_CAST
+# undef INTEGER_TYPE
+#endif
+
+#ifdef INCLUDE_UINT16
+# define PROCESS process_u16
+# define TYPE uint16_t
+# define SCAN_TYPE SCNu16
+# define PRINT_TYPE "u"
+# define PRINT_CAST unsigned
+# define INTEGER_TYPE
+# include FILE
+# undef PROCESS
+# undef TYPE
+# undef SCAN_TYPE
+# undef PRINT_TYPE
+# undef PRINT_CAST
+# undef INTEGER_TYPE
+#endif
+
+#ifdef INCLUDE_UINT32
+# define PROCESS process_u32
+# define TYPE uint32_t
+# define SCAN_TYPE SCNu32
+# define PRINT_TYPE PRIu32
+# define PRINT_CAST uint32_t
+# define INTEGER_TYPE
+# include FILE
+# undef PROCESS
+# undef TYPE
+# undef SCAN_TYPE
+# undef PRINT_TYPE
+# undef PRINT_CAST
+# undef INTEGER_TYPE
+#endif
+
+#ifdef INCLUDE_UINT64
+# define PROCESS process_u64
+# define TYPE uint64_t
+# define SCAN_TYPE SCNu64
+# define PRINT_TYPE PRIu64
+# define PRINT_CAST uint64_t
+# define INTEGER_TYPE
+# include FILE
+# undef PROCESS
+# undef TYPE
+# undef SCAN_TYPE
+# undef PRINT_TYPE
+# undef PRINT_CAST
+# undef INTEGER_TYPE
+#endif
diff --git a/src/generate-macros.c b/src/generate-macros.c
index ef87ad5..165c168 100644
--- a/src/generate-macros.c
+++ b/src/generate-macros.c
@@ -1,9 +1,40 @@
+/* See LICENSE file for copyright and license details. */
#include <stdint.h>
#include <stdio.h>
int
main(void)
{
+ char *u16 = (char *)&(uint16_t){0x0001};
+ char *u32 = (char *)&(uint32_t){0x00010203};
+ char *u64 = (char *)&(uint64_t){0x0001020304050607};
+ int le16 = (u16[1] == 0 && u16[0] == 1);
+ int le32 = (u32[3] == 0 && u32[2] == 1 && u32[1] == 2 && u32[0] == 3);
+ int le64 = (u64[7] == 0 && u64[6] == 1 && u64[5] == 2 && u64[4] == 3 &&
+ u64[3] == 4 && u64[2] == 5 && u64[1] == 6 && u64[0] == 7);
+ int be16 = (u16[0] == 0 && u16[1] == 1);
+ int be32 = (u32[0] == 0 && u32[1] == 1 && u32[2] == 2 && u32[3] == 3);
+ int be64 = (u64[0] == 0 && u64[1] == 1 && u64[2] == 2 && u64[3] == 3 &&
+ u64[4] == 4 && u64[5] == 5 && u64[6] == 6 && u64[7] == 7);
+
+ if (le16)
+ printf("#define HOST_ENDIAN_IS_LITTLE_ENDIAN_16\n");
+ if (le32)
+ printf("#define HOST_ENDIAN_IS_LITTLE_ENDIAN_32\n");
+ if (le64)
+ printf("#define HOST_ENDIAN_IS_LITTLE_ENDIAN_64\n");
+ if (le16 && le32 && le64)
+ printf("#define HOST_ENDIAN_IS_LITTLE_ENDIAN\n");
+
+ if (be16)
+ printf("#define HOST_ENDIAN_IS_BIG_ENDIAN_16\n");
+ if (be32)
+ printf("#define HOST_ENDIAN_IS_BIG_ENDIAN_32\n");
+ if (be64)
+ printf("#define HOST_ENDIAN_IS_BIG_ENDIAN_64\n");
+ if (be16 && be32 && be64)
+ printf("#define HOST_ENDIAN_IS_BIG_ENDIAN\n");
+
if (sizeof(float) == 4) {
unsigned long int a, b;
a = (unsigned long int)*(uint32_t *)&(float){ (float)(1. / 12.) };
@@ -18,5 +49,6 @@ main(void)
printf("#define USING_BINARY64 %i\n",
a == 0x3fb5555555555555ULL && b == 0xbfb5555555555555ULL);
}
+
return 0;
}
diff --git a/src/stream.c b/src/stream.c
index b69f9a5..ef57b93 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -95,6 +95,8 @@ enopen_stream(int status, struct stream *stream, const char *file)
int
set_pixel_format(struct stream *stream, const char *pixfmt)
{
+#define TEST_ENCODING_AGNOSTIC(FMT) (!strcmp(stream->pixfmt, FMT) || !strcmp(stream->pixfmt, FMT" f"))
+
if (pixfmt) {
pixfmt = get_pixel_format(pixfmt, "xyza");
if (strlen(pixfmt) >= sizeof(stream->pixfmt))
@@ -102,27 +104,101 @@ set_pixel_format(struct stream *stream, const char *pixfmt)
strcpy(stream->pixfmt, pixfmt);
}
+ stream->n_chan = 4;
+ stream->alpha = UNPREMULTIPLIED;
+ stream->encoding = DOUBLE;
+ stream->endian = HOST_ENDIAN;
+ stream->alpha_chan = 3;
+ stream->luma_chan = -1;
+
if (!strcmp(stream->pixfmt, "xyza")) {
- stream->n_chan = 4;
- stream->chan_size = sizeof(double);
stream->space = CIEXYZ;
- stream->alpha = UNPREMULTIPLIED;
- stream->encoding = DOUBLE;
} else if (!strcmp(stream->pixfmt, "xyza f")) {
- stream->n_chan = 4;
- stream->chan_size = sizeof(float);
stream->space = CIEXYZ;
- stream->alpha = UNPREMULTIPLIED;
stream->encoding = FLOAT;
+ } else if (!strcmp(stream->pixfmt, "raw0")) {
+ stream->space = YUV_NONLINEAR;
+ stream->encoding = UINT16;
+ stream->endian = LITTLE_ENDIAN;
+ stream->alpha_chan = 0;
+ stream->luma_chan = 1;
+ } else if (!strcmp(stream->pixfmt, "raw1")) {
+ stream->space = YUV_NONLINEAR;
+ stream->encoding = UINT16;
+ stream->endian = LITTLE_ENDIAN;
+ } else if (!strcmp(stream->pixfmt, "raw2a") || !strcmp(stream->pixfmt, "raw2")) {
+ stream->space = YUV_NONLINEAR;
+ stream->alpha = stream->pixfmt[4] == 'a' ? UNPREMULTIPLIED : NO_ALPHA;
+ stream->encoding = UINT16;
+ } else if (TEST_ENCODING_AGNOSTIC("raw3") || TEST_ENCODING_AGNOSTIC("raw3a")) {
+ stream->space = YUV_NONLINEAR;
+ stream->alpha = stream->pixfmt[4] == 'a' ? UNPREMULTIPLIED : NO_ALPHA;
+ stream->encoding = strlen(stream->pixfmt) > 6 ? FLOAT : DOUBLE;
+ } else if (TEST_ENCODING_AGNOSTIC("raw4") || TEST_ENCODING_AGNOSTIC("raw4a")) {
+ stream->space = CIEXYZ_NONLINEAR;
+ stream->alpha = stream->pixfmt[4] == 'a' ? UNPREMULTIPLIED : NO_ALPHA;
+ stream->encoding = strlen(stream->pixfmt) > 6 ? FLOAT : DOUBLE;
+ } else if (TEST_ENCODING_AGNOSTIC("raw5") || TEST_ENCODING_AGNOSTIC("raw5a")) {
+ stream->space = SRGB_NONLINEAR;
+ stream->alpha = stream->pixfmt[4] == 'a' ? UNPREMULTIPLIED : NO_ALPHA;
+ stream->encoding = strlen(stream->pixfmt) > 6 ? FLOAT : DOUBLE;
+ } else if (TEST_ENCODING_AGNOSTIC("raw6") || TEST_ENCODING_AGNOSTIC("raw6a")) {
+ stream->space = SRGB;
+ stream->alpha = stream->pixfmt[4] == 'a' ? UNPREMULTIPLIED : NO_ALPHA;
+ stream->encoding = strlen(stream->pixfmt) > 6 ? FLOAT : DOUBLE;
} else {
return -1;
}
+ if (stream->alpha == NO_ALPHA) {
+ stream->n_chan -= 1;
+ stream->alpha_chan = -1;
+ }
+
+ if (stream->luma_chan == -1) {
+ switch (stream->space) {
+ case CIEXYZ:
+ case CIEXYZ_NONLINEAR:
+ stream->luma_chan = 1;
+ break;
+ case YUV_NONLINEAR:
+ stream->luma_chan = 0;
+ break;
+ default:
+ break;
+ }
+ }
+
+ switch (stream->encoding) {
+ case DOUBLE:
+ stream->chan_size = sizeof(double);
+ break;
+ case FLOAT:
+ stream->chan_size = sizeof(float);
+ break;
+ case UINT8:
+ stream->chan_size = sizeof(uint8_t);
+ break;
+ case UINT16:
+ stream->chan_size = sizeof(uint16_t);
+ break;
+ case UINT32:
+ stream->chan_size = sizeof(uint32_t);
+ break;
+ case UINT64:
+ stream->chan_size = sizeof(uint64_t);
+ break;
+ default:
+ abort();
+ }
+
stream->pixel_size = stream->n_chan * stream->chan_size;
stream->row_size = stream->pixel_size * stream->width;
stream->col_size = stream->pixel_size * stream->height;
stream->frame_size = stream->pixel_size * stream->height * stream->width;
return 0;
+
+#undef TEST_ENCODING_AGNOSTIC
}
void
@@ -235,30 +311,107 @@ const char *
get_pixel_format(const char *specified, const char *current)
{
enum colour_space space;
- enum encoding encoding;
+ enum alpha alpha = UNPREMULTIPLIED;
+ enum encoding encoding = DOUBLE;
+ enum endian endian = HOST_ENDIAN;
+ int alpha_first = 0;
if (!strcmp(current, "xyza"))
- space = CIEXYZ, encoding = DOUBLE;
+ space = CIEXYZ;
else if (!strcmp(current, "xyza f"))
- space = CIEXYZ, encoding = FLOAT;
+ space = CIEXYZ;
+ else if (!strcmp(current, "raw0"))
+ space = YUV_NONLINEAR, encoding = UINT16, endian = LITTLE_ENDIAN, alpha_first = 1;
+ else if (!strcmp(current, "raw1"))
+ space = YUV_NONLINEAR, encoding = UINT16, endian = LITTLE_ENDIAN;
+ else if (!strcmp(current, "raw2"))
+ space = YUV_NONLINEAR, encoding = UINT16, alpha = NO_ALPHA;
+ else if (!strcmp(current, "raw2a"))
+ space = YUV_NONLINEAR, encoding = UINT16;
+ else if (!strcmp(current, "raw3"))
+ space = YUV_NONLINEAR, alpha = NO_ALPHA;
+ else if (!strcmp(current, "raw3a"))
+ space = YUV_NONLINEAR;
+ else if (!strcmp(current, "raw4"))
+ space = CIEXYZ_NONLINEAR, alpha = NO_ALPHA;
+ else if (!strcmp(current, "raw4a"))
+ space = CIEXYZ_NONLINEAR;
+ else if (!strcmp(current, "raw5"))
+ space = SRGB_NONLINEAR, alpha = NO_ALPHA;
+ else if (!strcmp(current, "raw5a"))
+ space = SRGB_NONLINEAR;
+ else if (!strcmp(current, "raw6"))
+ space = SRGB, alpha = NO_ALPHA;
+ else if (!strcmp(current, "raw6a"))
+ space = SRGB;
else
return specified;
if (!strcmp(specified, "xyza"))
- space = CIEXYZ;
- else if (!strcmp(specified, "xyza f"))
- return "xyza f";
+ space = CIEXYZ, alpha = UNPREMULTIPLIED;
else if (!strcmp(specified, "xyza !f"))
return "xyza";
else if (!strcmp(specified, "f"))
encoding = FLOAT;
else if (!strcmp(specified, "!f"))
encoding = DOUBLE;
+ else if (!strcmp(specified, "raw3 !f"))
+ return "raw3";
+ else if (!strcmp(specified, "raw3a !f"))
+ return "raw3a";
+ else if (!strcmp(specified, "raw4 !f"))
+ return "raw4";
+ else if (!strcmp(specified, "raw4a !f"))
+ return "raw4a";
+ else if (!strcmp(specified, "raw5 !f"))
+ return "raw5";
+ else if (!strcmp(specified, "raw5a !f"))
+ return "raw5a";
+ else if (!strcmp(specified, "raw6 !f"))
+ return "raw6";
+ else if (!strcmp(specified, "raw6a !f"))
+ return "raw6a";
+ else if (!strcmp(specified, "raw3"))
+ space = YUV_NONLINEAR, alpha = NO_ALPHA;
+ else if (!strcmp(specified, "raw4"))
+ space = CIEXYZ_NONLINEAR, alpha = NO_ALPHA;
+ else if (!strcmp(specified, "raw5"))
+ space = SRGB_NONLINEAR, alpha = NO_ALPHA;
+ else if (!strcmp(specified, "raw6"))
+ space = SRGB, alpha = NO_ALPHA;
+ else if (!strcmp(specified, "raw3a"))
+ space = YUV_NONLINEAR, alpha = UNPREMULTIPLIED;
+ else if (!strcmp(specified, "raw4a"))
+ space = CIEXYZ_NONLINEAR, alpha = UNPREMULTIPLIED;
+ else if (!strcmp(specified, "raw5a"))
+ space = SRGB_NONLINEAR, alpha = UNPREMULTIPLIED;
+ else if (!strcmp(specified, "raw6a"))
+ space = SRGB, alpha = UNPREMULTIPLIED;
else
return specified;
- if (space == CIEXYZ)
+ if (space == CIEXYZ && alpha == UNPREMULTIPLIED)
return encoding == FLOAT ? "xyza f" : "xyza";
+ else if (space == YUV_NONLINEAR && alpha == UNPREMULTIPLIED && encoding == UINT16 && endian == LITTLE_ENDIAN)
+ return alpha_first ? "raw0" : "raw1";
+ else if (space == YUV_NONLINEAR && encoding == UINT16)
+ return alpha ? "raw2" : "raw2a";
+ else if (space == YUV_NONLINEAR && encoding == DOUBLE)
+ return alpha ? "raw3" : "raw3a";
+ else if (space == YUV_NONLINEAR && encoding == FLOAT)
+ return alpha ? "raw3 f" : "raw3a f";
+ else if (space == CIEXYZ_NONLINEAR && encoding == DOUBLE)
+ return alpha ? "raw4" : "raw4a";
+ else if (space == CIEXYZ_NONLINEAR && encoding == FLOAT)
+ return alpha ? "raw4 f" : "raw4a f";
+ else if (space == SRGB_NONLINEAR && encoding == DOUBLE)
+ return alpha ? "raw5" : "raw5a";
+ else if (space == SRGB_NONLINEAR && encoding == FLOAT)
+ return alpha ? "raw5 f" : "raw5a f";
+ else if (space == SRGB && encoding == DOUBLE)
+ return alpha ? "raw6" : "raw6a";
+ else if (space == SRGB && encoding == FLOAT)
+ return alpha ? "raw6 f" : "raw6a f";
else
return specified;
}
diff --git a/src/stream.h b/src/stream.h
index b85c6c6..2d27cba 100644
--- a/src/stream.h
+++ b/src/stream.h
@@ -64,16 +64,33 @@ enum dimension {
};
enum colour_space {
- CIEXYZ
+ CIEXYZ,
+ CIEXYZ_NONLINEAR,
+ YUV_NONLINEAR,
+ SRGB_NONLINEAR,
+ SRGB
};
enum alpha {
- UNPREMULTIPLIED
+ NO_ALPHA,
+ UNPREMULTIPLIED,
+ PREMULTIPLIED /* not used */
};
enum encoding {
FLOAT,
- DOUBLE
+ DOUBLE,
+ LONG_DOUBLE, /* not used */
+ UINT8, /* not used */
+ UINT16,
+ UINT32, /* not used */
+ UINT64 /* not used */
+};
+
+enum endian {
+ HOST_ENDIAN,
+ LITTLE_ENDIAN,
+ BIG_ENDIAN /* not used */
};
struct stream {
@@ -87,6 +104,9 @@ struct stream {
enum colour_space space;
enum alpha alpha;
enum encoding encoding;
+ enum endian endian;
+ short int alpha_chan;
+ short int luma_chan;
int fd;
size_t ptr;
size_t xptr;
diff --git a/src/util/endian.h b/src/util/endian.h
index dfe9e77..1ec9d66 100644
--- a/src/util/endian.h
+++ b/src/util/endian.h
@@ -9,6 +9,31 @@
#if !defined(HAVE_ENDIAN_H) && !defined(HAVE_SYS_ENDIAN_H)
+# if defined(HOST_ENDIAN_IS_LITTLE_ENDIAN_16)
+# if !defined(htole16)
+# define htole16(x) (x)
+# endif
+# if !defined(htole16)
+# define letoh16(x) (x)
+# endif
+# endif
+# if defined(HOST_ENDIAN_IS_LITTLE_ENDIAN_32)
+# if !defined(htole32)
+# define htole32(x) (x)
+# endif
+# if !defined(htole32)
+# define letoh32(x) (x)
+# endif
+# endif
+# if defined(HOST_ENDIAN_IS_LITTLE_ENDIAN_64)
+# if !defined(htole64)
+# define htole16(x) (x)
+# endif
+# if !defined(htole64)
+# define letoh16(x) (x)
+# endif
+# endif
+
# if !defined(htole16)
# define htole16 blind_htole16
static inline uint16_t