Introduction
Introduction Statistics Contact Development Disclaimer Help
blind-to-portable.c - blind - suckless command-line video editing utility
git clone git://git.suckless.org/blind
Log
Files
Refs
README
LICENSE
---
blind-to-portable.c (4415B)
---
1 /* See LICENSE file for copyright and license details. */
2 #define INCLUDE_UINT16
3 #include "common.h"
4
5 /* Disable warnings in <math.h> */
6 #if defined(__clang__)
7 # pragma clang diagnostic ignored "-Wdouble-promotion"
8 # pragma clang diagnostic ignored "-Wconversion"
9 #endif
10
11 USAGE("[-s]")
12
13 static int strict = 1;
14
15 #define CONV(ITYPE, OTYPE, SOTYPE, EXPONENT, HA2EXPONENT, FRACTION)\
16 do {\
17 static int cache_i = 0;\
18 static ITYPE cache_in[] = {0, 0, 0, 0};\
19 static OTYPE cache_out[] = {0, 0, 0, 0};\
20 OTYPE signb, fraction, ret;\
21 SOTYPE exponent;\
22 ITYPE u, dexponent;\
23 if (host == cache_in[cache_i]) {\
24 ret = cache_out[cache_i++];\
25 cache_i &= 3;\
26 return ret;\
27 }\
28 cache_in[cache_i] = host;\
29 signb = (OTYPE)signbit(host);\
30 u = signb ? -host : host;\
31 if (g_isnan(host) || g_isinf(host)) {\
32 ret = ((((OTYPE)1 << EXPONENT) - (OTYPE)1) << FR…
33 } else if (u == (ITYPE)0.0) {\
34 ret = 0;\
35 } else {\
36 dexponent = log2(u);\
37 exponent = (SOTYPE)dexponent;\
38 if (u == pow((ITYPE)2.0, (ITYPE)exponent)) {\
39 exponent += HA2EXPONENT;\
40 fraction = 0;\
41 } else {\
42 /* TODO subnormals are a bit rounded off…
43 u *= pow((ITYPE)2.0, (ITYPE)(FRACTION + …
44 fraction = (OTYPE)u;\
45 while (fraction >= (OTYPE)2 << FRACTION)…
46 fraction >>= 1;\
47 exponent += 1;\
48 }\
49 fraction &= ((OTYPE)1 << FRACTION) - 1;\
50 exponent += HA2EXPONENT - 1;\
51 }\
52 if (exponent < 1) {\
53 /* TODO subnormal result */\
54 exponent = 0;\
55 fraction = 0;\
56 } else if (exponent >= ((SOTYPE)1 << EXPONENT) -…
57 exponent = ((SOTYPE)1 << EXPONENT) - 1;\
58 fraction = 0;\
59 }\
60 ret = ((OTYPE)exponent << FRACTION) + fraction;\
61 }\
62 ret |= signb << (FRACTION + EXPONENT);\
63 cache_out[cache_i++] = ret;\
64 cache_i &= 3;\
65 return ret;\
66 } while (0)
67
68 #define PROCESS_FLOAT(ITYPE, OTYPE, BITS)\
69 do {\
70 size_t i, n;\
71 ITYPE *ibuf = (ITYPE *)(stream->buf);\
72 OTYPE *obuf = sizeof(ITYPE) == sizeof(OTYPE) ? (OTYPE *)…
73 : alloca(sizeof(stream->buf) / sizeof(ITYPE) * s…
74 strict *= !USING_BINARY##BITS;\
75 if (!strict && sizeof(ITYPE) != sizeof(OTYPE))\
76 eprintf("-s is supported not on this machine\n")…
77 if (stream->endian == LITTLE && !strict) {\
78 esend_stream(stream, STDOUT_FILENO, "<stdout>");\
79 break;\
80 }\
81 do {\
82 n = stream->ptr / sizeof(ITYPE);\
83 if (strict) {\
84 for (i = 0; i < n; i++)\
85 obuf[i] = htole(conv_##ITYPE(ibu…
86 } else {\
87 for (i = 0; i < n; i++)\
88 obuf[i] = htole(*(OTYPE *)&ibuf[…
89 }\
90 ewriteall(STDOUT_FILENO, obuf, n * sizeof(OTYPE)…
91 n *= sizeof(ITYPE);\
92 memmove(stream->buf, stream->buf + n, stream->pt…
93 } while (eread_stream(stream, SIZE_MAX));\
94 if (stream->ptr)\
95 eprintf("%s: incomplete frame\n", stream->file);\
96 } while (0)
97
98 #define PROCESS_INTEGER(TYPE)\
99 do {\
100 size_t i, n;\
101 TYPE *buf = (TYPE *)(stream->buf);\
102 if (stream->endian == LITTLE) {\
103 esend_stream(stream, STDOUT_FILENO, "<stdout>");\
104 break;\
105 }\
106 do {\
107 n = stream->ptr / sizeof(TYPE);\
108 for (i = 0; i < n; i++)\
109 buf[i] = htole(buf[i]);\
110 n *= sizeof(TYPE);\
111 ewriteall(STDOUT_FILENO, buf, n, "<stdout>");\
112 memmove(stream->buf, stream->buf + n, stream->pt…
113 } while (eread_stream(stream, SIZE_MAX));\
114 if (stream->ptr)\
115 eprintf("%s: incomplete frame\n", stream->file);\
116 } while (0)
117
118 static uint64_t conv_double(double host) {CONV(double, uint64_t, int64_t…
119 static uint32_t conv_float (float host) {CONV(float, uint32_t, int32_t…
120
121 static void process_lf (struct stream *stream) {PROCESS_FLOAT(double, ui…
122 static void process_f (struct stream *stream) {PROCESS_FLOAT(float, ui…
123 static void process_u16(struct stream *stream) {PROCESS_INTEGER(uint16_t…
124
125 int
126 main(int argc, char *argv[])
127 {
128 struct stream stream;
129 void (*process)(struct stream *stream);
130
131 ARGBEGIN {
132 case 's':
133 strict = 0;
134 break;
135 default:
136 usage();
137 } ARGEND;
138
139 if (argc)
140 usage();
141
142 eopen_stream(&stream, NULL);
143 #if defined(HOST_ENDIAN_IS_LITTLE_ENDIAN)
144 if (stream.endian == HOST)
145 stream.endian = LITTLE;
146 #elif defined(HOST_ENDIAN_IS_BIG_ENDIAN)
147 if (stream.endian == HOST)
148 stream.endian = BIG;
149 #endif
150
151 SELECT_PROCESS_FUNCTION(&stream);
152 fprint_stream_head(stdout, &stream);
153 efflush(stdout, "<stdout>");
154 process(&stream);
155 return 0;
156 }
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.