commit e7d073bf6fa91c43753ab67644d067e2ce5881a7
parent 687e7aa9abf91f1bade59213a8b53f9bb4ec4186
Author: Mattias Andrée <maandree@kth.se>
Date: Sat, 13 May 2017 13:52:29 +0200
Add blind-to-portable and blind-from-portable
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat:
5 files changed, 331 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
@@ -16,6 +16,7 @@ BIN =\
blind-flip\
blind-flop\
blind-from-image\
+ blind-from-portable\
blind-from-text\
blind-from-video\
blind-gauss-blur\
@@ -34,6 +35,7 @@ BIN =\
blind-stack\
blind-time-blur\
blind-to-image\
+ blind-to-portable\
blind-to-text\
blind-to-video\
blind-translate\
diff --git a/TODO b/TODO
@@ -14,7 +14,7 @@ blind-affine-colour apply an affine transformation to the colour of each pixel,
-l for linear transformation,
-p for transforming each pixel with their own transformation.
blind-invert-chroma invert the chroma
-blind-from-sent convert a sent presentation to a one-frame-per-slide blind video
+blind-from-sent convert a sent presentation to a one-frame-per-slide blind video.
blind-from-video: add options to:
* just run ffmpeg just print the output
@@ -26,6 +26,11 @@ blind-from-video: add options to:
Add [-j jobs] to blind-from-video and blind-to-video.
+Generate a header file with the appropriate values for USING_BINARY32, USING_BINARY64.
+long double is slightly faster than long.
+long double (xyza q) could be added as another format.
+unsigned char (xyza 8) could be added as another format, it's probably good for previewing
+
HELP REQUIRED:
blind-z-map create a Z-map video from two or more videos
diff --git a/src/blind-from-portable.c b/src/blind-from-portable.c
@@ -0,0 +1,117 @@
+/* See LICENSE file for copyright and license details. */
+#include "stream.h"
+#include "util.h"
+
+#include <alloca.h>
+#include <math.h>
+#include <string.h>
+
+USAGE("[-s]")
+
+#define USING_BINARY32 0
+#define USING_BINARY64 0
+
+#define CONV(ITYPE, SITYPE, OTYPE, EXPONENT, HA2EXPONENT, FRACTION, SUFFIX)\
+ do {\
+ static int cache_i = 0;\
+ static ITYPE cache_in[] = {0, 0, 0, 0};\
+ static OTYPE cache_out[] = {0, 0, 0, 0};\
+ ITYPE exponent, fraction, signb;\
+ SITYPE sexponent;\
+ OTYPE ret, dexponent;\
+ if (portable == cache_in[cache_i]) {\
+ ret = cache_out[cache_i++];\
+ cache_i &= 3;\
+ return ret;\
+ }\
+ signb = portable >> (EXPONENT + FRACTION);\
+ exponent = (portable >> FRACTION) ^ (signb << EXPONENT);\
+ fraction = portable & (((ITYPE)1 << FRACTION) - 1);\
+ if (!exponent) {\
+ if (!fraction) {\
+ ret = (OTYPE)0.0;\
+ } else {\
+ sexponent = 1 - HA2EXPONENT - FRACTION;\
+ dexponent = (OTYPE)sexponent;\
+ ret = (ITYPE)fraction;\
+ ret *= pow##SUFFIX((OTYPE)2.0, dexponent);\
+ }\
+ } else if (exponent + 1 == (ITYPE)1 << EXPONENT) {\
+ ret = (OTYPE)(fraction ? NAN : INFINITY);\
+ } else {\
+ fraction |= (ITYPE)1 << FRACTION;\
+ sexponent = (SITYPE)exponent;\
+ sexponent -= HA2EXPONENT + FRACTION;\
+ dexponent = (OTYPE)sexponent;\
+ ret = (ITYPE)fraction;\
+ ret *= pow##SUFFIX((OTYPE)2.0, dexponent);\
+ }\
+ ret = signb ? -ret : ret;\
+ cache_out[cache_i++] = ret;\
+ cache_i &= 3;\
+ return ret;\
+ } while (0)
+
+#define PROCESS(ITYPE, OTYPE, BITS)\
+ do {\
+ size_t i, n;\
+ ITYPE *ibuf = (ITYPE *)(stream->buf);\
+ OTYPE *obuf = sizeof(ITYPE) == sizeof(OTYPE) ? (OTYPE *)(stream->buf)\
+ : 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");\
+ do {\
+ n = stream->ptr / sizeof(ITYPE);\
+ if (strict) {\
+ for (i = 0; i < n; i++)\
+ obuf[i] = conv_##OTYPE(le##BITS##toh(ibuf[i]));\
+ } else {\
+ for (i = 0; i < n; i++)\
+ obuf[i] = *(OTYPE *)&(ITYPE){le##BITS##toh(ibuf[i])};\
+ }\
+ ewriteall(STDOUT_FILENO, obuf, n * sizeof(OTYPE), "<stdout>");\
+ n *= sizeof(ITYPE);\
+ 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, f);}
+
+static void process_xyza (struct stream *stream, int strict) {PROCESS(uint64_t, double, 64);}
+static void process_xyzaf(struct stream *stream, int strict) {PROCESS(uint32_t, float, 32);}
+
+int
+main(int argc, char *argv[])
+{
+ struct stream stream;
+ int strict = 0;
+ void (*process)(struct stream *stream, int strict);
+
+ ARGBEGIN {
+ case 's':
+ strict = 1;
+ break;
+ default:
+ usage();
+ } ARGEND;
+ if (argc)
+ usage();
+
+ eopen_stream(&stream, NULL);
+
+ if (!strcmp(stream.pixfmt, "xyza"))
+ process = process_xyza;
+ else if (!strcmp(stream.pixfmt, "xyza f"))
+ process = process_xyzaf;
+ else
+ eprintf("pixel format %s is not supported\n", stream.pixfmt);
+
+ fprint_stream_head(stdout, &stream);
+ efflush(stdout, "<stdout>");
+ process(&stream, strict);
+ return 0;
+}
diff --git a/src/blind-to-portable.c b/src/blind-to-portable.c
@@ -0,0 +1,128 @@
+/* See LICENSE file for copyright and license details. */
+#include "stream.h"
+#include "util.h"
+
+#include <alloca.h>
+#include <math.h>
+#include <string.h>
+
+USAGE("[-s]")
+
+#define USING_BINARY32 0
+#define USING_BINARY64 0
+
+#define CONV(ITYPE, OTYPE, SOTYPE, EXPONENT, HA2EXPONENT, FRACTION, SUFFIX)\
+ do {\
+ static int cache_i = 0;\
+ static ITYPE cache_in[] = {0, 0, 0, 0};\
+ static OTYPE cache_out[] = {0, 0, 0, 0};\
+ OTYPE signb, fraction, ret;\
+ SOTYPE exponent;\
+ ITYPE u, dexponent;\
+ if (host == cache_in[cache_i]) {\
+ ret = cache_out[cache_i++];\
+ cache_i &= 3;\
+ return ret;\
+ }\
+ signb = signbit(host);\
+ u = signb ? -host : host;\
+ if (isnan(host) || !isfinite(host)) {\
+ ret = ((((OTYPE)1 << EXPONENT) - 1) << FRACTION) | !isinf(host);\
+ } else if (u == (ITYPE)0.0) {\
+ ret = 0;\
+ } else {\
+ dexponent = log2##SUFFIX(u);\
+ exponent = (SOTYPE)dexponent;\
+ if (u == pow##SUFFIX(2.0, (ITYPE)exponent)) {\
+ exponent += HA2EXPONENT;\
+ fraction = 0;\
+ } else {\
+ /* TODO subnormals are a bit rounded off */\
+ u *= pow##SUFFIX(2.0, (ITYPE)(FRACTION + 1 - exponent));\
+ fraction = u;\
+ while (fraction >= (OTYPE)2 << FRACTION) {\
+ fraction >>= 1;\
+ exponent += 1;\
+ }\
+ fraction &= ((OTYPE)1 << FRACTION) - 1;\
+ exponent += HA2EXPONENT - 1;\
+ }\
+ if (exponent < 1) {\
+ /* TODO subnormal result */\
+ exponent = 0;\
+ fraction = 0;\
+ } else if (exponent >= ((SOTYPE)1 << EXPONENT) - (SOTYPE)1) { \
+ exponent = ((SOTYPE)1 << EXPONENT) - (SOTYPE)1;\
+ fraction = 0;\
+ }\
+ ret = (exponent << FRACTION) + fraction;\
+ }\
+ ret |= signb << (FRACTION + EXPONENT);\
+ cache_out[cache_i++] = ret;\
+ cache_i &= 3;\
+ return ret;\
+ } while (0)
+
+#define PROCESS(ITYPE, OTYPE, BITS)\
+ do {\
+ size_t i, n;\
+ ITYPE *ibuf = (ITYPE *)(stream->buf);\
+ OTYPE *obuf = sizeof(ITYPE) == sizeof(OTYPE) ? (OTYPE *)(stream->buf)\
+ : 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");\
+ do {\
+ n = stream->ptr / sizeof(ITYPE);\
+ if (strict) {\
+ for (i = 0; i < n; i++)\
+ obuf[i] = htole##BITS(conv_##ITYPE(ibuf[i]));\
+ } else {\
+ for (i = 0; i < n; i++)\
+ obuf[i] = htole##BITS(*(OTYPE *)&ibuf[i]);\
+ }\
+ ewriteall(STDOUT_FILENO, obuf, n * sizeof(OTYPE), "<stdout>");\
+ n *= sizeof(ITYPE);\
+ 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, f);}
+
+static void process_xyza (struct stream *stream, int strict) {PROCESS(double, uint64_t, 64);}
+static void process_xyzaf(struct stream *stream, int strict) {PROCESS(float, uint32_t, 32);}
+
+int
+main(int argc, char *argv[])
+{
+ struct stream stream;
+ int strict = 0;
+ void (*process)(struct stream *stream, int strict);
+
+ ARGBEGIN {
+ case 's':
+ strict = 1;
+ break;
+ default:
+ usage();
+ } ARGEND;
+ if (argc)
+ usage();
+
+ eopen_stream(&stream, NULL);
+
+ if (!strcmp(stream.pixfmt, "xyza"))
+ process = process_xyza;
+ else if (!strcmp(stream.pixfmt, "xyza f"))
+ process = process_xyzaf;
+ else
+ eprintf("pixel format %s is not supported\n", stream.pixfmt);
+
+ fprint_stream_head(stdout, &stream);
+ efflush(stdout, "<stdout>");
+ process(&stream, strict);
+ return 0;
+}
diff --git a/src/util/endian.h b/src/util/endian.h
@@ -24,6 +24,44 @@ blind_htole16(uint16_t h)
}
# endif
+# if !defined(htole32)
+# define htole32 blind_htole32
+static inline uint32_t
+blind_htole32(uint32_t h)
+{
+ union {
+ unsigned char bytes[4];
+ uint32_t value;
+ } d;
+ d.bytes[0] = h;
+ d.bytes[1] = h >> 8;
+ d.bytes[2] = h >> 16;
+ d.bytes[3] = h >> 24;
+ return d.value;
+}
+# endif
+
+# if !defined(htole64)
+# define htole64 blind_htole64
+static inline uint64_t
+blind_htole64(uint64_t h)
+{
+ union {
+ unsigned char bytes[8];
+ uint64_t value;
+ } d;
+ d.bytes[0] = h;
+ d.bytes[1] = h >> 8;
+ d.bytes[2] = h >> 16;
+ d.bytes[3] = h >> 24;
+ d.bytes[4] = h >> 32;
+ d.bytes[5] = h >> 40;
+ d.bytes[6] = h >> 48;
+ d.bytes[7] = h >> 56;
+ return d.value;
+}
+# endif
+
# if !defined(le16toh)
# if defined(letoh16)
# define le16toh letoh16
@@ -38,6 +76,46 @@ blind_le16toh(uint16_t le)
# endif
# endif
+# if !defined(le32toh)
+# if defined(letoh32)
+# define le32toh letoh32
+# else
+# define le32toh blind_le32toh
+static inline uint32_t
+blind_le32toh(uint32_t le)
+{
+ unsigned char *bytes = (unsigned char *)≤
+ return ((uint32_t)(bytes[3]) << 24) |
+ ((uint32_t)(bytes[2]) << 16) |
+ ((uint32_t)(bytes[1]) << 8) |
+ (uint32_t)(bytes[0]);
+}
+# endif
+# endif
+
+# if !defined(le64toh)
+# if defined(letoh64)
+# define le64toh letoh64
+# else
+# define le64toh blind_le64toh
+static inline uint64_t
+blind_le64toh(uint64_t le)
+{
+ unsigned char *bytes = (unsigned char *)≤
+ return ((uint64_t)(bytes[7]) << 56) |
+ ((uint64_t)(bytes[6]) << 48) |
+ ((uint64_t)(bytes[5]) << 40) |
+ ((uint64_t)(bytes[4]) << 32) |
+ ((uint64_t)(bytes[3]) << 24) |
+ ((uint64_t)(bytes[2]) << 16) |
+ ((uint64_t)(bytes[1]) << 8) |
+ (uint64_t)(bytes[0]);
+}
+# endif
+# endif
+
#elif defined(HAVE_OPENBSD_ENDIAN)
# define le16toh letoh16
+# define le32toh letoh32
+# define le64toh letoh64
#endif