commit b640dfad6fd5c0ae3a9bfdd9b4bd54e387b0cc51
Author:     Mattias Andrée <maand...@kth.se>
AuthorDate: Sun Aug 6 02:52:29 2017 +0200
Commit:     Mattias Andrée <maand...@kth.se>
CommitDate: Sun Aug 6 02:52:29 2017 +0200

    Update blind-convert to support unconverted output from ffmpeg and 
partially converted output
    
    Signed-off-by: Mattias Andrée <maand...@kth.se>

diff --git a/man/blind-convert.1 b/man/blind-convert.1
index 500ebaa..1dd3834 100644
--- a/man/blind-convert.1
+++ b/man/blind-convert.1
@@ -78,67 +78,45 @@ 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
+.B raw4 !f
 Host-endian, double-precision float-point sR'G'B'.
 .TP
-.B raw5
+.B raw4
 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
+.B raw4a f
 Host-endian, single-precision float-point sR'G'B'A.
 .TP
-.B raw5a !f
+.B raw4a !f
 Host-endian, double-precision float-point sR'G'B'A.
 .TP
-.B raw5a
+.B raw4a
 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
+.B raw5 f
 Host-endian, single-precision float-point sRGB.
 .TP
-.B raw6 !f
+.B raw5 !f
 Host-endian, double-precision float-point sRGB.
 .TP
-.B raw6
+.B raw5
 Host-endian, double-precision float-point sRGB,
 but single-precision float-point if input is
 single-precision float-point.
 .TP
-.B raw6a f
+.B raw5a f
 Host-endian, single-precision float-point sRGBA.
 .TP
-.B raw6a !f
+.B raw5a !f
 Host-endian, double-precision float-point sRGBA.
 .TP
-.B raw6a
+.B raw5a
 Host-endian, double-precision float-point sRGBA,
 but single-precision float-point if input is
 single-precision float-point.
diff --git a/man/blind-from-video.1 b/man/blind-from-video.1
index 68e355b..71cbccb 100644
--- a/man/blind-from-video.1
+++ b/man/blind-from-video.1
@@ -50,17 +50,6 @@ 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
diff --git a/src/blind-affine-colour.c b/src/blind-affine-colour.c
index f7bda25..2c45460 100644
--- a/src/blind-affine-colour.c
+++ b/src/blind-affine-colour.c
@@ -41,7 +41,7 @@ main(int argc, char *argv[])
 
        SELECT_PROCESS_FUNCTION(&colour);
        if (skip_alpha && colour.alpha_chan != -1)
-               CHECK_CHANS(&colour, == colour.n_chan - 1, == colour.luma_chan);
+               CHECK_CHANS(&colour, == (short int)(colour.n_chan - 1), == 
colour.luma_chan);
        else
                skip_alpha = 0;
 
diff --git a/src/blind-convert.c b/src/blind-convert.c
index e0ffc0f..8f14367 100644
--- a/src/blind-convert.c
+++ b/src/blind-convert.c
@@ -3,80 +3,380 @@
 
 USAGE("pixel-format ...")
 
-static void (*outconv)(double *xyzas, size_t n);
+static int in_level = INT_MAX;
+static int out_level = INT_MAX;
 
-#define INCONV(TYPE)\
+static void
+lf_to_f(double *in, float *out, size_t n)
+{
+       size_t i;
+       for (i = 0; i < n; i++)
+               out[i] = (float)(in[i]);
+}
+
+static void
+f_to_lf(double *in, float *out, size_t n)
+{
+       size_t i;
+       for (i = 0; i < n; i++)
+               out[i] = (double)(in[i]);
+}
+
+#if !defined(HOST_ENDIAN_IS_LITTLE_ENDIAN_16)
+static void
+le_to_h_16(uint16_t *buf, size_t n)
+{
+       size_t i;
+       for (i = 0; i < n; i++)
+               buf[i] = letoh(buf[i]);
+}
+
+static void
+h_to_le_16(uint16_t *buf, size_t n)
+{
+       size_t i;
+       for (i = 0; i < n; i++)
+               buf[i] = htole(buf[i]);
+}
+#else
+# define le_to_h_16(buf, n) ((void) buf, (void) n)
+# define h_to_le_16(buf, n) ((void) buf, (void) n)
+#endif
+
+static size_t
+remove_alpha_u16(uint16_t *buf, size_t n)
+{
+       size_t i, j;
+       long int a, max = (long int)UINT16_MAX;
+       for (i = j = 0; i < n; i += 4, j += 3) {
+               a = (long int)(buf[i + 3]);
+               buf[j + 0] = (uint16_t)(((long int)(buf[i + 0]) -  16L * 256L) 
* a / max +  16L * 256L);
+               buf[j + 1] = (uint16_t)(((long int)(buf[i + 1]) - 128L * 256L) 
* a / max + 128L * 256L);
+               buf[j + 2] = (uint16_t)(((long int)(buf[i + 2]) - 128L * 256L) 
* a / max + 128L * 256L);
+       }
+       return j;
+}
+
+#define REMOVE_ALPHA()\
+       do {\
+               size_t i, j;\
+               for (i = j = 0; i < n; i += 4, j += 3) {\
+                       buf[j + 0] = buf[i + 0] * buf[i + 3];\
+                       buf[j + 1] = buf[i + 1] * buf[i + 3];\
+                       buf[j + 2] = buf[i + 2] * buf[i + 3];\
+               }\
+               return j;\
+       } while (0)
+
+static size_t remove_alpha_lf(double *buf, size_t n) { REMOVE_ALPHA(); }
+static size_t remove_alpha_f (float  *buf, size_t n) { REMOVE_ALPHA(); }
+
+#define ADD_ALPHA(TYPE, MAX)\
+       do {\
+               size_t i = n, j = n + n / 3;\
+               for (; i; i -= 3, j -= 4) {\
+                       out[j - 1] = (TYPE)(MAX);\
+                       out[j - 2] = in[i - 1];\
+                       out[j - 3] = in[i - 2];\
+                       out[j - 4] = in[i - 3];\
+               }\
+               return n + n / 3;\
+       } while (0)
+
+static size_t add_alpha_u16(uint16_t *in, uint16_t *out, size_t n) { 
ADD_ALPHA(uint16_t, UINT16_MAX); }
+static size_t add_alpha_lf (double   *in, double   *out, size_t n) { 
ADD_ALPHA(double,   1); }
+static size_t add_alpha_f  (float    *in, float    *out, size_t n) { 
ADD_ALPHA(float,    1); }
+
+static void
+raw0_to_raw1(uint16_t *buf, size_t n)
+{
+       size_t i;
+       uint16_t t;
+       for (i = 0; i < n; i += 4, buf += 4)
+               t = buf[0], buf[0] = buf[1], buf[1] = buf[2], buf[2] = buf[3], 
buf[3] = t;
+}
+
+static void
+raw1_to_raw0(uint16_t *buf, size_t n)
+{
+       size_t i;
+       uint16_t t;
+       for (i = 0; i < n; i += 4, buf += 4)
+               t = buf[3], buf[3] = buf[2], buf[2] = buf[1], buf[1] = buf[0], 
buf[0] = t;
+}
+
+#define RAW2_TO_RAW3(TYPE, WITH_ALPHA)\
+       do {\
+               size_t i;\
+               TYPE max = (TYPE)UINT16_MAX;\
+               if (sizeof(*in) > sizeof(*out)) {\
+                       for (i = 0; i < n; i += 3 + WITH_ALPHA) {\
+                               out[i + 0] = (TYPE)((long int)(in[i + 0]) -  
16L * 256L) / max;\
+                               out[i + 1] = (TYPE)((long int)(in[i + 1]) - 
128L * 256L) / max;\
+                               out[i + 2] = (TYPE)((long int)(in[i + 2]) - 
128L * 256L) / max;\
+                               if (WITH_ALPHA)\
+                                       out[i + 3] = (TYPE)(in[i + 3]) / max;\
+                       }\
+               } else {\
+                       for (i = n; i; i -= 3 + WITH_ALPHA) {\
+                               if (WITH_ALPHA)\
+                                       out[i - 1] = (TYPE)(in[i - 1]) / max;\
+                               out[i - 1 - WITH_ALPHA] = (TYPE)((long 
int)(in[i - 1 - WITH_ALPHA]) - 128L * 256L) / max;\
+                               out[i - 2 - WITH_ALPHA] = (TYPE)((long 
int)(in[i - 2 - WITH_ALPHA]) - 128L * 256L) / max;\
+                               out[i - 3 - WITH_ALPHA] = (TYPE)((long 
int)(in[i - 3 - WITH_ALPHA]) -  16L * 256L) / max;\
+                       }\
+               }\
+       } while (0)
+
+static void raw2_to_raw3_lf  (uint16_t *in, double *out, size_t n) { 
RAW2_TO_RAW3(double, 0); }
+static void raw2_to_raw3_f   (uint16_t *in, float  *out, size_t n) { 
RAW2_TO_RAW3(float,  0); }
+static void raw2a_to_raw3a_lf(uint16_t *in, double *out, size_t n) { 
RAW2_TO_RAW3(double, 1); }
+static void raw2a_to_raw3a_f (uint16_t *in, float  *out, size_t n) { 
RAW2_TO_RAW3(float,  1); }
+
+#define RAW3_TO_RAW2(TYPE, WITH_ALPHA)\
        do {\
-               double buf[sizeof(stream->buf) / (4 * sizeof(TYPE)) * 4];\
-               double *interm;\
-               TYPE *in;\
-               size_t n, m;\
-               do {\
-                       in = (TYPE *)stream->buf;\
-                       interm = buf;\
-                       n = stream->ptr / stream->pixel_size;\
-                       for (m = n; m--; in += 4, interm += 4) { \
-                               interm[0] = (double)(in[0]);\
-                               interm[1] = (double)(in[1]);\
-                               interm[2] = (double)(in[2]);\
-                               interm[3] = (double)(in[3]);\
+               size_t i;\
+               TYPE max = (TYPE)UINT16_MAX;\
+               long int y, u, v;\
+               if (sizeof(*in) > sizeof(*out)) {\
+                       for (i = 0; i < n; i += 3 + WITH_ALPHA) {\
+                               y = (long int)(in[i + 0] * max) +  16L * 256L;\
+                               u = (long int)(in[i + 1] * max) + 128L * 256L;\
+                               v = (long int)(in[i + 2] * max) + 128L * 256L;\
+                               out[i + 0] = (uint16_t)CLIP(0, y, 0xFFFFL);\
+                               out[i + 1] = (uint16_t)CLIP(0, u, 0xFFFFL);\
+                               out[i + 2] = (uint16_t)CLIP(0, v, 0xFFFFL);\
+                               if (WITH_ALPHA) {\
+                                       v = (long int)(in[i + 3] * max);\
+                                       out[i + 3] = (uint16_t)CLIP(0, v, 
0xFFFFL);\
+                               }\
+                       }\
+               } else {\
+                       for (i = n; i; i -= 3 + WITH_ALPHA) {\
+                               if (WITH_ALPHA) {\
+                                       v = (long int)(in[i - 1] * max);\
+                                       out[i - 1] = (uint16_t)CLIP(0, v, 
0xFFFFL); \
+                               }\
+                               v = (long int)(in[i - 1 - WITH_ALPHA] * max) + 
128L * 256L;\
+                               u = (long int)(in[i - 2 - WITH_ALPHA] * max) + 
128L * 256L;\
+                               y = (long int)(in[i - 3 - WITH_ALPHA] * max) +  
16L * 256L;\
+                               out[i - 1 - WITH_ALPHA] = (uint16_t)CLIP(0, v, 
0xFFFFL);\
+                               out[i - 2 - WITH_ALPHA] = (uint16_t)CLIP(0, u, 
0xFFFFL);\
+                               out[i - 3 - WITH_ALPHA] = (uint16_t)CLIP(0, y, 
0xFFFFL);\
                        }\
-                       outconv(buf, n);\
-                       n *= stream->pixel_size;\
-                       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)
 
-#define OUTCONV(TYPE)\
+static void raw3_to_raw2_lf  (double *in, uint16_t *out, size_t n) { 
RAW3_TO_RAW2(double, 0); }
+static void raw3_to_raw2_f   (float  *in, uint16_t *out, size_t n) { 
RAW3_TO_RAW2(float,  0); }
+static void raw3a_to_raw2a_lf(double *in, uint16_t *out, size_t n) { 
RAW3_TO_RAW2(double, 1); }
+static void raw3a_to_raw2a_f (float  *in, uint16_t *out, size_t n) { 
RAW3_TO_RAW2(float,  1); }
+
+#define CONVERT_COLOUR_SPACE(TYPE, CONV)\
        do {\
-               TYPE *out = alloca(n * 4 * sizeof(TYPE));\
-               size_t i, m = n * 4;\
-               for (i = 0; i < m; i++)\
-                       out[i] = (TYPE)(xyzas[i]);\
-               ewriteall(STDOUT_FILENO, out, n * 4 * sizeof(TYPE), 
"<stdout>");\
+               size_t i, s = 3 + (size_t)a;\
+               for (i = 0; i < n; i += s)\
+                       CONV(buf[i + 0], buf[i + 1], buf[i + 2], buf + i + 0, 
buf + i + 1, buf + i + 2);\
        } while (0)
 
-static void inconv_xyza (struct stream *stream) {INCONV(double);}
-static void inconv_xyzaf(struct stream *stream) {INCONV(float);}
+static void conv_yuv_to_srgb_lf(double *buf, size_t n, int a) { 
CONVERT_COLOUR_SPACE(double, yuv_to_srgb); }
+static void conv_yuv_to_srgb_f (float  *buf, size_t n, int a) { 
CONVERT_COLOUR_SPACE(float,  yuv_to_srgb); }
+static void conv_srgb_to_yuv_lf(double *buf, size_t n, int a) { 
CONVERT_COLOUR_SPACE(double, srgb_to_yuv); }
+static void conv_srgb_to_yuv_f (float  *buf, size_t n, int a) { 
CONVERT_COLOUR_SPACE(float,  srgb_to_yuv); }
+static void conv_xyz_to_srgb_lf(double *buf, size_t n, int a) { 
CONVERT_COLOUR_SPACE(double, ciexyz_to_srgb); }
+static void conv_xyz_to_srgb_f (float  *buf, size_t n, int a) { 
CONVERT_COLOUR_SPACE(float,  ciexyz_to_srgb); }
+static void conv_srgb_to_xyz_lf(double *buf, size_t n, int a) { 
CONVERT_COLOUR_SPACE(double, srgb_to_ciexyz); }
+static void conv_srgb_to_xyz_f (float  *buf, size_t n, int a) { 
CONVERT_COLOUR_SPACE(float,  srgb_to_ciexyz); }
+
+#define CHANGE_TRANSFER(TYPE, CONV)\
+       do {\
+               size_t i, s = 3 + (size_t)a;\
+               for (i = 0; i < n; i += s) {\
+                       buf[i + 0] = CONV(buf[i + 0]);\
+                       buf[i + 1] = CONV(buf[i + 1]);\
+                       buf[i + 2] = CONV(buf[i + 2]);\
+               }\
+       } while (0)
+
+static void conv_srgbt_to_srgb_lf(double *buf, size_t n, int a) { 
CHANGE_TRANSFER(double, srgb_decode); }
+static void conv_srgbt_to_srgb_f (float  *buf, size_t n, int a) { 
CHANGE_TRANSFER(float,  srgb_decode); }
+static void conv_srgb_to_srgbt_lf(double *buf, size_t n, int a) { 
CHANGE_TRANSFER(double, srgb_encode); }
+static void conv_srgb_to_srgbt_f (float  *buf, size_t n, int a) { 
CHANGE_TRANSFER(float,  srgb_encode); }
+
+#define CONVERT_COLOUR_SPACE_AUTO(CONV)\
+       static void\
+       conv_##CONV(enum encoding encoding, int with_alpha, void *buf, size_t 
n)\
+       {\
+               if (encoding == DOUBLE)\
+                       conv_##CONV##_lf(buf, n, !!with_alpha);\
+               else\
+                       conv_##CONV##_f(buf, n, !!with_alpha);\
+       }
+CONVERT_COLOUR_SPACE_AUTO(yuv_to_srgb)
+CONVERT_COLOUR_SPACE_AUTO(srgb_to_yuv)
+CONVERT_COLOUR_SPACE_AUTO(xyz_to_srgb)
+CONVERT_COLOUR_SPACE_AUTO(srgb_to_xyz)
+CONVERT_COLOUR_SPACE_AUTO(srgbt_to_srgb)
+CONVERT_COLOUR_SPACE_AUTO(srgb_to_srgbt)
+
+static void
+convert(struct stream *stream, struct stream *out, void *buf, size_t n)
+{
+       enum encoding encoding = stream->encoding;
+
+       if (in_level <= 0 && out_level > 0)
+               raw0_to_raw1(buf, n);
 
-static void outconv_xyza (double *xyzas, size_t n) {OUTCONV(double);}
-static void outconv_xyzaf(double *xyzas, size_t n) {OUTCONV(float);}
+       if (in_level <= 1 && out_level > 1)
+               le_to_h_16(buf, n);
+
+       if (in_level <= 2 && out_level > 2) {
+               if (out->encoding == DOUBLE && stream->alpha)
+                       raw2a_to_raw3a_lf(buf, buf, n);
+               else if (out->encoding == FLOAT && stream->alpha)
+                       raw2a_to_raw3a_f(buf, buf, n);
+               else if (out->encoding == DOUBLE)
+                       raw2_to_raw3_lf(buf, buf, n);
+               else if (out->encoding == FLOAT)
+                       raw2_to_raw3_f(buf, buf, n);
+               encoding = out->encoding;
+       } else if (stream->encoding == FLOAT && out->encoding == DOUBLE) {
+               f_to_lf(buf, buf, n);
+               encoding = out->encoding;
+       } else if (stream->encoding == DOUBLE && out->encoding == FLOAT) {
+               lf_to_f(buf, buf, n);
+               encoding = out->encoding;
+       }
+
+       if (stream->alpha && !out->alpha) {
+               if (encoding == DOUBLE)
+                       n = remove_alpha_lf(buf, n);
+               else if (encoding == FLOAT)
+                       n = remove_alpha_f(buf, n);
+               else
+                       n = remove_alpha_u16(buf, n);
+       } else if (!stream->alpha && out->alpha) {
+               if (encoding == DOUBLE)
+                       n = add_alpha_lf(buf, buf, n);
+               else if (encoding == FLOAT)
+                       n = add_alpha_f(buf, buf, n);
+               else
+                       n = add_alpha_u16(buf, buf, n);
+       }
+
+       if (stream->space == CIEXYZ && out->space == YUV_NONLINEAR) {
+               conv_xyz_to_srgb(encoding, out->alpha, buf, n);
+               conv_srgb_to_srgbt(encoding, out->alpha, buf, n);
+               conv_srgb_to_yuv(encoding, out->alpha, buf, n);
+       } else if (stream->space == CIEXYZ && out->space == SRGB_NONLINEAR) {
+               conv_xyz_to_srgb(encoding, out->alpha, buf, n);
+               conv_srgb_to_srgbt(encoding, out->alpha, buf, n);
+       } else if (stream->space == CIEXYZ && out->space == SRGB) {
+               conv_xyz_to_srgb(encoding, out->alpha, buf, n);
+       } else if (stream->space == YUV_NONLINEAR && out->space == CIEXYZ) {
+               conv_yuv_to_srgb(encoding, out->alpha, buf, n);
+               conv_srgbt_to_srgb(encoding, out->alpha, buf, n);
+               conv_srgb_to_xyz(encoding, out->alpha, buf, n);
+       } else if (stream->space == YUV_NONLINEAR && out->space == 
SRGB_NONLINEAR) {
+               conv_yuv_to_srgb(encoding, out->alpha, buf, n);
+       } else if (stream->space == YUV_NONLINEAR && out->space == SRGB) {
+               conv_yuv_to_srgb(encoding, out->alpha, buf, n);
+               conv_srgbt_to_srgb(encoding, out->alpha, buf, n);
+       } else if (stream->space == SRGB_NONLINEAR && out->space == CIEXYZ) {
+               conv_srgbt_to_srgb(encoding, out->alpha, buf, n);
+               conv_srgb_to_xyz(encoding, out->alpha, buf, n);
+       } else if (stream->space == SRGB_NONLINEAR && out->space == 
YUV_NONLINEAR) {
+               conv_srgb_to_yuv(encoding, out->alpha, buf, n);
+       } else if (stream->space == SRGB_NONLINEAR && out->space == SRGB) {
+               conv_srgbt_to_srgb(encoding, out->alpha, buf, n);
+       } else if (stream->space == SRGB && out->space == CIEXYZ) {
+               conv_srgb_to_xyz(encoding, out->alpha, buf, n);
+       } else if (stream->space == SRGB && out->space == YUV_NONLINEAR) {
+               conv_srgb_to_srgbt(encoding, out->alpha, buf, n);
+               conv_srgb_to_yuv(encoding, out->alpha, buf, n);
+       } else if (stream->space == SRGB && out->space == SRGB_NONLINEAR) {
+               conv_srgb_to_srgbt(encoding, out->alpha, buf, n);
+       }
+
+       if (out_level <= 2 && in_level > 2) {
+               if (encoding == DOUBLE && out->alpha)
+                       raw3a_to_raw2a_lf(buf, buf, n);
+               else if (encoding == FLOAT && out->alpha)
+                       raw3a_to_raw2a_f(buf, buf, n);
+               else if (encoding == DOUBLE)
+                       raw3_to_raw2_lf(buf, buf, n);
+               else if (encoding == FLOAT)
+                       raw3_to_raw2_f(buf, buf, n);
+       }
+
+       if (out_level <= 1 && in_level > 1)
+               h_to_le_16(buf, n);
+
+       if (out_level <= 0 && in_level > 0)
+               raw1_to_raw0(buf, n);
+
+       ewriteall(STDOUT_FILENO, buf, n * out->chan_size, "<stdout>");
+}
 
 int
 main(int argc, char *argv[])
 {
-       struct stream stream;
+       struct stream stream, out;
        const char *pixfmt;
-       void (*inconv)(struct stream *stream);
+       void *buf = NULL;
+       size_t n;
 
        UNOFLAGS(!argc);
 
        eopen_stream(&stream, NULL);
 
-       if (!strcmp(stream.pixfmt, "xyza"))
-               inconv = inconv_xyza;
-       else if (!strcmp(stream.pixfmt, "xyza f"))
-               inconv = inconv_xyzaf;
-       else
-               eprintf("input pixel format %s is not supported\n", 
stream.pixfmt);
-
+       memcpy(&out, &stream, sizeof(out));
        pixfmt = stream.pixfmt;
        while (*argv)
                pixfmt = get_pixel_format(*argv++, pixfmt);
-
-       if (!strcmp(pixfmt, "xyza"))
-               outconv = outconv_xyza;
-       else if (!strcmp(pixfmt, "xyza f"))
-               outconv = outconv_xyzaf;
-       else
+       strcpy(out.pixfmt, pixfmt);
+       if (set_pixel_format(&out, NULL))
                eprintf("output pixel format %s is not supported\n", pixfmt);
 
-       strcpy(stream.pixfmt, pixfmt);
-       fprint_stream_head(stdout, &stream);
+       fprint_stream_head(stdout, &out);
        efflush(stdout, "<stdout>");
 
-       inconv(&stream);
+       if (!strcmp(stream.pixfmt, out.pixfmt)) {
+               esend_stream(&stream, STDOUT_FILENO, "<stdout>");
+               return 0;
+       }
+
+       if (stream.alpha_chan == 0)
+               in_level = 0;
+       else if (stream.endian == LITTLE)
+               in_level = 1;
+       else if (stream.encoding == UINT16)
+               in_level = 2;
+       if (out.alpha_chan == 0)
+               out_level = 0;
+       else if (out.endian == LITTLE)
+               out_level = 1;
+       else if (out.encoding == UINT16)
+               out_level = 2;
+
+       if (out.encoding == UINT16)
+               out.encoding = stream.encoding;
+
+       n = MAX(stream.chan_size, out.chan_size) * MAX(stream.n_chan, 
out.n_chan);
+       if (n > stream.pixel_size)
+               buf = emalloc(sizeof(stream.buf) / stream.chan_size * n);
+
+       do {
+               n = stream.ptr / stream.pixel_size * stream.n_chan;
+               if (buf)
+                       memcpy(buf, stream.buf, n * stream.chan_size);
+               convert(&stream, &out, buf ? buf : stream.buf, n);
+               n *= stream.chan_size;
+               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);
+
+       free(buf);
        return 0;
 }
diff --git a/src/blind-dissolve.c b/src/blind-dissolve.c
index b78121e..5735381 100644
--- a/src/blind-dissolve.c
+++ b/src/blind-dissolve.c
@@ -10,7 +10,7 @@ static int reverse = 0;
 
 #define PROCESS(TYPE)\
        do {\
-               size_t i = stream->alpha_chan * stream->chan_size;\
+               size_t i = (size_t)(stream->alpha_chan) * stream->chan_size;\
                TYPE a = fm ? (TYPE)(reverse ? f : fm - f) / fm_##TYPE : 
(TYPE)0.5;\
                for (; i < n; i += stream->pixel_size)\
                        *(TYPE *)(stream->buf + i) *= a;\
diff --git a/src/blind-from-named.c b/src/blind-from-named.c
index 04c6e91..95f6998 100644
--- a/src/blind-from-named.c
+++ b/src/blind-from-named.c
@@ -48,7 +48,7 @@ main(int argc, char *argv[])
        int filedes = -1;
        int tries = 11;
        int sockfd, fd;
-       ssize_t n;
+       size_t n;
 
        ARGBEGIN {
        case 'a':
@@ -108,6 +108,6 @@ retry:
        }
 
        while ((n = eread(fd, buf, sizeof(buf), "<received file>")))
-               ewriteall(STDOUT_FILENO, buf, (size_t)n, "<stdout>");
+               ewriteall(STDOUT_FILENO, buf, n, "<stdout>");
        return 0;
 }
diff --git a/src/blind-from-portable.c b/src/blind-from-portable.c
index e80510b..4551ab6 100644
--- a/src/blind-from-portable.c
+++ b/src/blind-from-portable.c
@@ -57,7 +57,7 @@ static int strict = 1;
                strict *= !USING_BINARY##BITS;\
                if (!strict && sizeof(ITYPE) != sizeof(OTYPE))\
                        eprintf("-s is supported not on this machine\n");\
-               if (stream->endian == HOST_ENDIAN && !strict) {\
+               if (stream->endian == HOST && !strict) {\
                        esend_stream(stream, STDOUT_FILENO, "<stdout>");\
                        break;\
                }\
@@ -82,7 +82,7 @@ static int strict = 1;
        do {\
                size_t i, n;\
                TYPE *buf = (TYPE *)(stream->buf);\
-               if (stream->endian == HOST_ENDIAN) {\
+               if (stream->endian == HOST) {\
                        esend_stream(stream, STDOUT_FILENO, "<stdout>");\
                        break;\
                }\
@@ -124,11 +124,11 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 #if defined(HOST_ENDIAN_IS_LITTLE_ENDIAN)
-       if (stream.endian == LITTLE_ENDIAN)
-               stream.endian = HOST_ENDIAN;
+       if (stream.endian == LITTLE)
+               stream.endian = HOST;
 #elif defined(HOST_ENDIAN_IS_BIG_ENDIAN)
-       if (stream.endian == BIG_ENDIAN)
-               stream.endian = HOST_ENDIAN;
+       if (stream.endian == BIG)
+               stream.endian = HOST;
 #endif
 
        SELECT_PROCESS_FUNCTION(&stream);
diff --git a/src/blind-mosaic-corners.c b/src/blind-mosaic-corners.c
index 83c33bf..524d17e 100644
--- a/src/blind-mosaic-corners.c
+++ b/src/blind-mosaic-corners.c
@@ -86,10 +86,10 @@ main(int argc, char *argv[])
                        j = 1;
                        memcpy(found, here, pixsize);
 
-                       dr = x != stream.width - 1 ? pixsize : tiled_x ? 
pixsize - stream.row_size : 0;
-                       dl = x ? -pixsize : tiled_x ? stream.row_size - pixsize 
: 0;
-                       dd = y != stream.height - 1 ? stream.row_size : tiled_y 
? stream.row_size - stream.frame_size : 0;
-                       du = y ? -stream.row_size : tiled_y ? stream.frame_size 
- stream.row_size : 0;
+                       dr = (ssize_t)(x != stream.width - 1 ? pixsize : 
tiled_x ? pixsize - stream.row_size : 0);
+                       dl = (ssize_t)(x ? -pixsize : tiled_x ? stream.row_size 
- pixsize : 0);
+                       dd = (ssize_t)(y != stream.height - 1 ? stream.row_size 
: tiled_y ? stream.row_size - stream.frame_size : 0);
+                       du = (ssize_t)(y ? -stream.row_size : tiled_y ? 
stream.frame_size - stream.row_size : 0);
 
                        memcpy(found + j++ * pixsize, here + dr, pixsize);
                        memcpy(found + j++ * pixsize, here + dl, pixsize);
diff --git a/src/blind-single-colour.c b/src/blind-single-colour.c
index 567a7f5..92a8289 100644
--- a/src/blind-single-colour.c
+++ b/src/blind-single-colour.c
@@ -77,8 +77,7 @@ PROCESS(void)
 {
        typedef TYPE pixel_t[4];
        pixel_t buf[BUFSIZ / 4];
-       size_t x, y, n;
-       ssize_t r;
+       size_t x, y, n, r;
        for (x = 0; x < ELEMENTSOF(buf); x++) {
                buf[x][0] = (TYPE)X;
                buf[x][1] = (TYPE)Y;
@@ -88,7 +87,7 @@ PROCESS(void)
        while (inf || stream.frames--)
                for (y = stream.height; y--;)
                        for (x = stream.width * sizeof(*buf); x;)
-                               for (x -= n = MIN(sizeof(buf), x); n; n -= 
(size_t)r)
+                               for (x -= n = MIN(sizeof(buf), x); n; n -= r)
                                        r = ewrite(STDOUT_FILENO, buf, n, 
"<stdout>");
 }
 
diff --git a/src/blind-to-portable.c b/src/blind-to-portable.c
index 07eee62..e5de707 100644
--- a/src/blind-to-portable.c
+++ b/src/blind-to-portable.c
@@ -74,7 +74,7 @@ static int strict = 1;
                strict *= !USING_BINARY##BITS;\
                if (!strict && sizeof(ITYPE) != sizeof(OTYPE))\
                        eprintf("-s is supported not on this machine\n");\
-               if (stream->endian == LITTLE_ENDIAN && !strict) {\
+               if (stream->endian == LITTLE && !strict) {\
                        esend_stream(stream, STDOUT_FILENO, "<stdout>");\
                        break;\
                }\
@@ -99,7 +99,7 @@ static int strict = 1;
        do {\
                size_t i, n;\
                TYPE *buf = (TYPE *)(stream->buf);\
-               if (stream->endian == LITTLE_ENDIAN) {\
+               if (stream->endian == LITTLE) {\
                        esend_stream(stream, STDOUT_FILENO, "<stdout>");\
                        break;\
                }\
@@ -141,11 +141,11 @@ main(int argc, char *argv[])
 
        eopen_stream(&stream, NULL);
 #if defined(HOST_ENDIAN_IS_LITTLE_ENDIAN)
-       if (stream.endian == HOST_ENDIAN)
-               stream.endian = LITTLE_ENDIAN;
+       if (stream.endian == HOST)
+               stream.endian = LITTLE;
 #elif defined(HOST_ENDIAN_IS_BIG_ENDIAN)
-       if (stream.endian == HOST_ENDIAN)
-               stream.endian = BIG_ENDIAN;
+       if (stream.endian == HOST)
+               stream.endian = BIG;
 #endif
 
        SELECT_PROCESS_FUNCTION(&stream);
diff --git a/src/blind-transition.c b/src/blind-transition.c
index 758857a..1be8e35 100644
--- a/src/blind-transition.c
+++ b/src/blind-transition.c
@@ -14,7 +14,7 @@ static struct stream softness;
 #define PROCESS(TYPE)\
        do {\
                size_t i, j = 0;\
-               TYPE a, s, t = fm ? (TYPE)(reverse ? fm - f : f) / fm_##TYPE : 
0.5;\
+               TYPE a, s, t = fm ? (TYPE)(reverse ? fm - f : f) / fm_##TYPE : 
(TYPE)0.5;\
                if (!softness_file) {\
                        for (i = 0; i < n; i += stream->pixel_size) {\
                                a = ((TYPE *)(stream->buf + i))[1];\
diff --git a/src/common.h b/src/common.h
index 3972389..731094d 100644
--- a/src/common.h
+++ b/src/common.h
@@ -66,7 +66,7 @@
 #endif
 
 #if !defined(PIPE_BUF)
-# define PIPE_BUF BUFSIZ
+# define PIPE_BUF 512
 #endif
 
 #ifndef DONT_INCLUDE_FLOAT
@@ -113,7 +113,7 @@
 
 #define SELECT_PROCESS_FUNCTION(stream)\
        do {\
-               if ((stream)->endian != HOST_ENDIAN)\
+               if ((stream)->endian != HOST)\
                        eprintf("pixel format %s is not supported, try xyza\n", 
(stream)->pixfmt);\
                SELECT_PROCESS_FUNCTION_FLOAT(stream);\
                SELECT_PROCESS_FUNCTION_DOUBLE(stream);\
diff --git a/src/stream.c b/src/stream.c
index ef57b93..d2b1158 100644
--- a/src/stream.c
+++ b/src/stream.c
@@ -98,7 +98,7 @@ 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");
+               pixfmt = get_pixel_format(pixfmt, stream->pixfmt[0] ? 
stream->pixfmt : "xyza");
                if (strlen(pixfmt) >= sizeof(stream->pixfmt))
                        return -1;
                strcpy(stream->pixfmt, pixfmt);
@@ -107,7 +107,7 @@ set_pixel_format(struct stream *stream, const char *pixfmt)
        stream->n_chan = 4;
        stream->alpha = UNPREMULTIPLIED;
        stream->encoding = DOUBLE;
-       stream->endian = HOST_ENDIAN;
+       stream->endian = HOST;
        stream->alpha_chan = 3;
        stream->luma_chan = -1;
 
@@ -119,13 +119,13 @@ set_pixel_format(struct stream *stream, const char 
*pixfmt)
        } else if (!strcmp(stream->pixfmt, "raw0")) {
                stream->space = YUV_NONLINEAR;
                stream->encoding = UINT16;
-               stream->endian = LITTLE_ENDIAN;
+               stream->endian = LITTLE;
                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;
+               stream->endian = LITTLE;
        } else if (!strcmp(stream->pixfmt, "raw2a") || !strcmp(stream->pixfmt, 
"raw2")) {
                stream->space = YUV_NONLINEAR;
                stream->alpha = stream->pixfmt[4] == 'a' ? UNPREMULTIPLIED : 
NO_ALPHA;
@@ -133,19 +133,15 @@ set_pixel_format(struct stream *stream, const char 
*pixfmt)
        } 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;
+               stream->encoding = strlen(stream->pixfmt) > 5 ? 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->encoding = strlen(stream->pixfmt) > 5 ? FLOAT : DOUBLE;
+       } else if (TEST_ENCODING_AGNOSTIC("raw5") || 
TEST_ENCODING_AGNOSTIC("raw5a")) {
                stream->space = SRGB;
                stream->alpha = stream->pixfmt[4] == 'a' ? UNPREMULTIPLIED : 
NO_ALPHA;
-               stream->encoding = strlen(stream->pixfmt) > 6 ? FLOAT : DOUBLE;
+               stream->encoding = strlen(stream->pixfmt) > 5 ? FLOAT : DOUBLE;
        } else {
                return -1;
        }
@@ -156,25 +152,21 @@ set_pixel_format(struct stream *stream, const char 
*pixfmt)
        }
 
        if (stream->luma_chan == -1) {
-               switch (stream->space) {
-               case CIEXYZ:
-               case CIEXYZ_NONLINEAR:
+               if (stream->space == CIEXYZ)
                        stream->luma_chan = 1;
-                       break;
-               case YUV_NONLINEAR:
+               else if (stream->space == YUV_NONLINEAR)
                        stream->luma_chan = 0;
-                       break;
-               default:
-                       break;
-               }
        }
 
        switch (stream->encoding) {
+       case FLOAT:
+               stream->chan_size = sizeof(float);
+               break;
        case DOUBLE:
                stream->chan_size = sizeof(double);
                break;
-       case FLOAT:
-               stream->chan_size = sizeof(float);
+       case LONG_DOUBLE:
+               stream->chan_size = sizeof(long double);
                break;
        case UINT8:
                stream->chan_size = sizeof(uint8_t);
@@ -310,108 +302,68 @@ encheck_compat(int status, const struct stream *a, const 
struct stream *b)
 const char *
 get_pixel_format(const char *specified, const char *current)
 {
-       enum colour_space space;
+       enum colour_space space = CIEXYZ;
        enum alpha alpha = UNPREMULTIPLIED;
-       enum encoding encoding = DOUBLE;
-       enum endian endian = HOST_ENDIAN;
-       int alpha_first = 0;
-
-       if (!strcmp(current, "xyza"))
-               space = CIEXYZ;
-       else if (!strcmp(current, "xyza f"))
-               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;
+       enum encoding encoding = UINT16;
+       int level = -1;
+       size_t n = strlen(specified);
+
+       if ((n >= 2 && !strcmp(specified - 2, " f")) ||
+           !strcmp(specified, "raw0") || !strcmp(specified, "raw1") ||
+           !strcmp(specified, "raw2") || !strcmp(specified, "raw2a"))
+               return specified;
+
+       if      (!strcmp(current, "xyza"))    space = CIEXYZ, encoding = DOUBLE;
+       else if (!strcmp(current, "xyza f"))  space = CIEXYZ, encoding = FLOAT;
+       else if (!strcmp(current, "raw0"))    level = 0;
+       else if (!strcmp(current, "raw1"))    level = 1;
+       else if (!strcmp(current, "raw2"))    level = 2, alpha = NO_ALPHA;
+       else if (!strcmp(current, "raw2a"))   level = 2;
+       else if (!strcmp(current, "raw3"))    level = 3, encoding = DOUBLE, 
alpha = NO_ALPHA;
+       else if (!strcmp(current, "raw3a"))   level = 3, encoding = DOUBLE;
+       else if (!strcmp(current, "raw3 f"))  level = 3, encoding = FLOAT, 
alpha = NO_ALPHA;
+       else if (!strcmp(current, "raw3a f")) level = 3, encoding = FLOAT;
+       else if (!strcmp(current, "raw4"))    level = 4, encoding = DOUBLE, 
alpha = NO_ALPHA;
+       else if (!strcmp(current, "raw4a"))   level = 4, encoding = DOUBLE;
+       else if (!strcmp(current, "raw4 f"))  level = 4, encoding = FLOAT, 
alpha = NO_ALPHA;
+       else if (!strcmp(current, "raw4a f")) level = 4, encoding = FLOAT;
+       else if (!strcmp(current, "raw5"))    level = 5, encoding = DOUBLE, 
alpha = NO_ALPHA;
+       else if (!strcmp(current, "raw5a"))   level = 5, encoding = DOUBLE;
+       else if (!strcmp(current, "raw5 f"))  level = 5, encoding = FLOAT, 
alpha = NO_ALPHA;
+       else if (!strcmp(current, "raw5a f")) level = 5, encoding = FLOAT;
        else
                return specified;
 
-       if (!strcmp(specified, "xyza"))
-               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;
+       if      (!strcmp(specified, "f"))        encoding = FLOAT;
+       else if (!strcmp(specified, "!f"))       encoding = DOUBLE;
+       else if (!strcmp(specified, "xyza"))     level = -1, alpha = 
UNPREMULTIPLIED, space = CIEXYZ;
+       else if (!strcmp(specified, "raw3"))     level = 3, alpha = NO_ALPHA;
+       else if (!strcmp(specified, "raw3a"))    level = 3, alpha = 
UNPREMULTIPLIED;
+       else if (!strcmp(specified, "raw4"))     level = 4, alpha = NO_ALPHA;
+       else if (!strcmp(specified, "raw4a"))    level = 4, alpha = 
UNPREMULTIPLIED;
+       else if (!strcmp(specified, "raw5"))     level = 5, alpha = NO_ALPHA;
+       else if (!strcmp(specified, "raw5a"))    level = 5, alpha = 
UNPREMULTIPLIED;
+       else if (!strcmp(specified, "xyza !f"))  return "xyza";
+       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
                return specified;
 
-       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";
+       if      (level == 0 && encoding == UINT16) return "raw0";
+       else if (level == 1 && encoding == UINT16) return "raw1";
+       else if (level == 2 && encoding == UINT16) return alpha ? "raw2a"   : 
"raw2";
+       else if (level == 3 && encoding == DOUBLE) return alpha ? "raw3a"   : 
"raw3";
+       else if (level == 3 && encoding == FLOAT)  return alpha ? "raw3a f" : 
"raw3 f";
+       else if (level == 4 && encoding == DOUBLE) return alpha ? "raw4a"   : 
"raw4";
+       else if (level == 4 && encoding == FLOAT)  return alpha ? "raw4a f" : 
"raw4 f";
+       else if (level == 5 && encoding == DOUBLE) return alpha ? "raw5a"   : 
"raw5";
+       else if (level == 5 && encoding == FLOAT)  return alpha ? "raw5a f" : 
"raw5 f";
+       else if (level < 0 && space == CIEXYZ && alpha == UNPREMULTIPLIED)
+               return encoding == FLOAT ? "xyza f" : encoding == DOUBLE ? 
"xyza" : specified;
        else
                return specified;
 }
diff --git a/src/stream.h b/src/stream.h
index 2d27cba..b36e4d3 100644
--- a/src/stream.h
+++ b/src/stream.h
@@ -65,7 +65,6 @@ enum dimension {
 
 enum colour_space {
        CIEXYZ,
-       CIEXYZ_NONLINEAR,
        YUV_NONLINEAR,
        SRGB_NONLINEAR,
        SRGB
@@ -88,9 +87,9 @@ enum encoding {
 };
 
 enum endian {
-       HOST_ENDIAN,
-       LITTLE_ENDIAN,
-       BIG_ENDIAN /* not used */
+       HOST,
+       LITTLE,
+       BIG /* not used */
 };
 
 struct stream {
diff --git a/src/util/colour.h b/src/util/colour.h
index 33f0347..7aafeae 100644
--- a/src/util/colour.h
+++ b/src/util/colour.h
@@ -57,68 +57,68 @@ SRGB_DECODE(float, _f, f)
        MATRIX_MULTIPLY_FUNCTION(FUNCTION_BASE##_f, float,  __VA_ARGS__)
 
 MATRIX_MULTIPLY_FUNCTIONS(yuv_to_srgb,
-                         1,
-                         0.00028328010485821202317155420580263580632163211703,
-                         1.14070449590558520291949662350816652178764343261719,
-                         1,
-                         -0.39630886669497211727275498560629785060882568359375,
-                         -0.58107364288228224857846271333983168005943298339844,
-                         1,
-                         2.03990003507541306504435851820744574069976806640625,
-                         0.00017179031692307700847528739718228507626918144524)
+                          1,
+                          0.00028328010485821202317155420580263580632163211703,
+                          1.14070449590558520291949662350816652178764343261719,
+                          1,
+                          
-0.39630886669497211727275498560629785060882568359375,
+                          
-0.58107364288228224857846271333983168005943298339844,
+                          1,
+                          2.03990003507541306504435851820744574069976806640625,
+                          0.00017179031692307700847528739718228507626918144524)
 
 MATRIX_MULTIPLY_FUNCTIONS(srgb_to_yuv,
-                         0.299, 0.587, 0.114,
-                         -0.14662756598240470062854967636667424812912940979004,
-                         -0.28771586836102963635752871596196200698614120483398,
-                          0.43434343434343436474165400795754976570606231689453,
-                          0.61456892577224520035628074765554629266262054443359,
-                         -0.51452282157676354490405401520547457039356231689453,
-                         -0.10004610419548178035231700278018251992762088775635)
+                          0.299, 0.587, 0.114,
+                          
-0.14662756598240470062854967636667424812912940979004,
+                          
-0.28771586836102963635752871596196200698614120483398,
+                           
0.43434343434343436474165400795754976570606231689453,
+                           
0.61456892577224520035628074765554629266262054443359,
+                          
-0.51452282157676354490405401520547457039356231689453,
+                          
-0.10004610419548178035231700278018251992762088775635)
 
 MATRIX_MULTIPLY_FUNCTIONS(ciexyz_to_srgb,
-                          3.240446254647737500675930277794,
-                         -1.537134761820080575134284117667,
-                         -0.498530193022728718155178739835,
-                         -0.969266606244679751469561779231,
-                          1.876011959788370209167851498933,
-                          0.041556042214430065351304932619,
-                          0.055643503564352832235773149705,
-                         -0.204026179735960239147729566866,
-                          1.057226567722703292062647051353)
+                           3.240446254647737500675930277794,
+                          -1.537134761820080575134284117667,
+                          -0.498530193022728718155178739835,
+                          -0.969266606244679751469561779231,
+                           1.876011959788370209167851498933,
+                           0.041556042214430065351304932619,
+                           0.055643503564352832235773149705,
+                          -0.204026179735960239147729566866,
+                           1.057226567722703292062647051353)
 
 MATRIX_MULTIPLY_FUNCTIONS(srgb_to_ciexyz,
-                         0.412457445582367576708548995157,
-                         0.357575865245515878143578447634,
-                         0.180437247826399665973085006954,
-                         0.212673370378408277403536885686,
-                         0.715151730491031756287156895269,
-                         0.072174899130559869164791564344,
-                         0.019333942761673460208893260415,
-                         0.119191955081838593666354597644,
-                         0.950302838552371742508739771438)
+                          0.412457445582367576708548995157,
+                          0.357575865245515878143578447634,
+                          0.180437247826399665973085006954,
+                          0.212673370378408277403536885686,
+                          0.715151730491031756287156895269,
+                          0.072174899130559869164791564344,
+                          0.019333942761673460208893260415,
+                          0.119191955081838593666354597644,
+                          0.950302838552371742508739771438)
 
 MATRIX_MULTIPLY_FUNCTIONS(scaled_yuv_to_ciexyz,
-                          0.00001450325106667098632156481796684488472237717360,
-                          0.00000345586790639342739093228633329157872822179343,
-                          0.00000400923398630552893485111398685916128670214675,
-                          0.00001525902189669641837040624243737596543724066578,
-                         -0.00000207722814409390653614547427030512238843584782,
-                         -0.00000263898607692305410302407824019166326934282552,
-                          0.00001661446153041708825425643025752719950105529279,
-                          0.00002885925752619118069149627137104374696718878113,
-                         -0.00000071781086875769179526501342566979779746816348)
+                           
0.00001450325106667098632156481796684488472237717360,
+                           
0.00000345586790639342739093228633329157872822179343,
+                           
0.00000400923398630552893485111398685916128670214675,
+                           
0.00001525902189669641837040624243737596543724066578,
+                          
-0.00000207722814409390653614547427030512238843584782,
+                          
-0.00000263898607692305410302407824019166326934282552,
+                           
0.00001661446153041708825425643025752719950105529279,
+                           
0.00002885925752619118069149627137104374696718878113,
+                          
-0.00000071781086875769179526501342566979779746816348)
 
 MATRIX_MULTIPLY_FUNCTIONS(ciexyz_to_scaled_yuv,
-                           26625.38231027395886485464870929718017578125,
-                           40524.0090949436053051613271236419677734375,
-                            -271.5313105642117079696618020534515380859375,
-                          -11278.3751445417292416095733642578125,
-                          -26409.91773157499847002327442169189453125,
-                           34100.5706543184860493056476116180419921875,
-                          162829.60100012840121053159236907958984375,
-                         -123829.313212639070115983486175537109375,
-                          -28411.65702312920984695665538311004638671875)
+                            26625.38231027395886485464870929718017578125,
+                            40524.0090949436053051613271236419677734375,
+                             -271.5313105642117079696618020534515380859375,
+                           -11278.3751445417292416095733642578125,
+                           -26409.91773157499847002327442169189453125,
+                            34100.5706543184860493056476116180419921875,
+                           162829.60100012840121053159236907958984375,
+                          -123829.313212639070115983486175537109375,
+                           -28411.65702312920984695665538311004638671875)
 
 #undef MATRIX_MULTIPLY_FUNCTIONS
 #undef MATRIX_MULTIPLY_FUNCTION
diff --git a/src/video-math.h b/src/video-math.h
index b768e10..69cc83d 100644
--- a/src/video-math.h
+++ b/src/video-math.h
@@ -139,19 +139,19 @@ degcos_f(float u)
 #define htole(A) (_Generic((A),\
                           uint8_t: (A),\
                            int8_t: (uint8_t)(A),\
-                          uint16_t: htole16(A),\
+                          uint16_t: htole16((uint16_t)(A)),\
                            int16_t: (uint16_t)htole16((uint16_t)(A)),\
-                          uint32_t: htole32(A),\
+                          uint32_t: htole32((uint32_t)(A)),\
                            int32_t: (uint32_t)htole32((uint32_t)(A)),\
-                          uint64_t: htole64(A),\
+                          uint64_t: htole64((uint64_t)(A)),\
                            int64_t: (uint64_t)htole64((uint64_t)(A))))
 
 #define letoh(A) (_Generic((A),\
                           uint8_t: (A),\
                            int8_t: (uint8_t)(A),\
-                          uint16_t: le16toh(A),\
+                          uint16_t: le16toh((uint16_t)(A)),\
                            int16_t: (uint16_t)le16toh((uint16_t)(A)),\
-                          uint32_t: le32toh(A),\
+                          uint32_t: le32toh((uint32_t)(A)),\
                            int32_t: (uint32_t)le32toh((uint32_t)(A)),\
-                          uint64_t: le64toh(A),\
+                          uint64_t: le64toh((uint64_t)(A)),\
                            int64_t: (uint64_t)le64toh((uint64_t)(A))))

Reply via email to