blind-from-portable.c - blind - suckless command-line video editing utility | |
git clone git://git.suckless.org/blind | |
Log | |
Files | |
Refs | |
README | |
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 *)… | |
56 : alloca(sizeof(stream->buf) / sizeof(ITYPE) * s… | |
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(ibu… | |
69 } else {\ | |
70 for (i = 0; i < n; i++)\ | |
71 obuf[i] = *(OTYPE *)&(ITYPE){let… | |
72 }\ | |
73 ewriteall(STDOUT_FILENO, obuf, n * sizeof(OTYPE)… | |
74 n *= sizeof(ITYPE);\ | |
75 memmove(stream->buf, stream->buf + n, stream->pt… | |
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->pt… | |
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, do… | |
102 static float conv_float (uint32_t portable) {CONV(uint32_t, int32_t, fl… | |
103 | |
104 static void process_lf (struct stream *stream) {PROCESS_FLOAT(uint64_t, … | |
105 static void process_f (struct stream *stream) {PROCESS_FLOAT(uint32_t, … | |
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 } |