commit e7d073bf6fa91c43753ab67644d067e2ce5881a7
Author:     Mattias Andrée <[email protected]>
AuthorDate: Sat May 13 13:52:29 2017 +0200
Commit:     Mattias Andrée <[email protected]>
CommitDate: Sat May 13 13:53:11 2017 +0200

    Add blind-to-portable and blind-from-portable
    
    Signed-off-by: Mattias Andrée <[email protected]>

diff --git a/Makefile b/Makefile
index c2444d8..0d9e5bd 100644
--- 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
index 163fd36..f0bbac6 100644
--- 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
new file mode 100644
index 0000000..ccb902d
--- /dev/null
+++ 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
new file mode 100644
index 0000000..9cb0448
--- /dev/null
+++ 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
index e6805b1..dfe9e77 100644
--- 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 *)&le;
+       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 *)&le;
+       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

Reply via email to