blind-from-portable.c - blind - suckless command-line video editing utility
(HTM) git clone git://git.suckless.org/blind
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
blind-from-portable.c (3967B)
---
1 /* See LICENSE file for copyright and license details. */
2 #define INCLUDE_UINT16
3 #include "common.h"
4
5 USAGE("[-s]")
6
7 static int strict = 1;
8
9 #define CONV(ITYPE, SITYPE, OTYPE, EXPONENT, HA2EXPONENT, FRACTION)\
10 do {\
11 static int cache_i = 0;\
12 static ITYPE cache_in[] = {0, 0, 0, 0};\
13 static OTYPE cache_out[] = {0, 0, 0, 0};\
14 ITYPE exponent, fraction, signb;\
15 SITYPE sexponent;\
16 OTYPE ret, dexponent;\
17 if (portable == cache_in[cache_i]) {\
18 ret = cache_out[cache_i++];\
19 cache_i &= 3;\
20 return ret;\
21 }\
22 cache_in[cache_i] = portable;\
23 signb = portable >> (EXPONENT + FRACTION);\
24 exponent = (portable >> FRACTION) ^ (signb << EXPONENT);\
25 fraction = portable & (((ITYPE)1 << FRACTION) - 1);\
26 if (!exponent) {\
27 if (!fraction) {\
28 ret = (OTYPE)0.0;\
29 } else {\
30 sexponent = 1 - HA2EXPONENT - FRACTION;\
31 dexponent = (OTYPE)sexponent;\
32 ret = (OTYPE)fraction;\
33 ret *= pow((OTYPE)2.0, dexponent);\
34 }\
35 } else if (exponent + 1 == (ITYPE)1 << EXPONENT) {\
36 ret = (OTYPE)(fraction ? NAN : INFINITY);\
37 } else {\
38 fraction |= (ITYPE)1 << FRACTION;\
39 sexponent = (SITYPE)exponent;\
40 sexponent -= HA2EXPONENT + FRACTION;\
41 dexponent = (OTYPE)sexponent;\
42 ret = (OTYPE)fraction;\
43 ret *= pow((OTYPE)2.0, dexponent);\
44 }\
45 ret = signb ? -ret : ret;\
46 cache_out[cache_i++] = ret;\
47 cache_i &= 3;\
48 return ret;\
49 } while (0)
50
51 #define PROCESS_FLOAT(ITYPE, OTYPE, BITS)\
52 do {\
53 size_t i, n;\
54 ITYPE *ibuf = (ITYPE *)(stream->buf);\
55 OTYPE *obuf = sizeof(ITYPE) == sizeof(OTYPE) ? (OTYPE *)(stream->buf)\
56 : alloca(sizeof(stream->buf) / sizeof(ITYPE) * sizeof(OTYPE));\
57 strict *= !USING_BINARY##BITS;\
58 if (!strict && sizeof(ITYPE) != sizeof(OTYPE))\
59 eprintf("-s is supported not on this machine\n");\
60 if (stream->endian == HOST && !strict) {\
61 esend_stream(stream, STDOUT_FILENO, "<stdout>");\
62 break;\
63 }\
64 do {\
65 n = stream->ptr / sizeof(ITYPE);\
66 if (strict) {\
67 for (i = 0; i < n; i++)\
68 obuf[i] = conv_##OTYPE(letoh(ibuf[i]));\
69 } else {\
70 for (i = 0; i < n; i++)\
71 obuf[i] = *(OTYPE *)&(ITYPE){letoh(ibuf[i])};\
72 }\
73 ewriteall(STDOUT_FILENO, obuf, n * sizeof(OTYPE), "<stdout>");\
74 n *= sizeof(ITYPE);\
75 memmove(stream->buf, stream->buf + n, stream->ptr -= n);\
76 } while (eread_stream(stream, SIZE_MAX));\
77 if (stream->ptr)\
78 eprintf("%s: incomplete frame\n", stream->file);\
79 } while (0)
80
81 #define PROCESS_INTEGER(TYPE)\
82 do {\
83 size_t i, n;\
84 TYPE *buf = (TYPE *)(stream->buf);\
85 if (stream->endian == HOST) {\
86 esend_stream(stream, STDOUT_FILENO, "<stdout>");\
87 break;\
88 }\
89 do {\
90 n = stream->ptr / sizeof(TYPE);\
91 for (i = 0; i < n; i++)\
92 buf[i] = letoh(buf[i]);\
93 n *= sizeof(TYPE);\
94 ewriteall(STDOUT_FILENO, buf, n, "<stdout>");\
95 memmove(stream->buf, stream->buf + n, stream->ptr -= n);\
96 } while (eread_stream(stream, SIZE_MAX));\
97 if (stream->ptr)\
98 eprintf("%s: incomplete frame\n", stream->file);\
99 } while (0)
100
101 static double conv_double(uint64_t portable) {CONV(uint64_t, int64_t, double, 11, 1023, 52);}
102 static float conv_float (uint32_t portable) {CONV(uint32_t, int32_t, float, 8, 127, 23);}
103
104 static void process_lf (struct stream *stream) {PROCESS_FLOAT(uint64_t, double, 64);}
105 static void process_f (struct stream *stream) {PROCESS_FLOAT(uint32_t, float, 32);}
106 static void process_u16(struct stream *stream) {PROCESS_INTEGER(uint16_t);}
107
108 int
109 main(int argc, char *argv[])
110 {
111 struct stream stream;
112 void (*process)(struct stream *stream);
113
114 ARGBEGIN {
115 case 's':
116 strict = 0;
117 break;
118 default:
119 usage();
120 } ARGEND;
121
122 if (argc)
123 usage();
124
125 eopen_stream(&stream, NULL);
126 #if defined(HOST_ENDIAN_IS_LITTLE_ENDIAN)
127 if (stream.endian == LITTLE)
128 stream.endian = HOST;
129 #elif defined(HOST_ENDIAN_IS_BIG_ENDIAN)
130 if (stream.endian == BIG)
131 stream.endian = HOST;
132 #endif
133
134 SELECT_PROCESS_FUNCTION(&stream);
135 fprint_stream_head(stdout, &stream);
136 efflush(stdout, "<stdout>");
137 process(&stream);
138 return 0;
139 }