Use alias-safe types in AV_[RW] macros
[ffmpeg.git] / libavutil / intreadwrite.h
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18
19 #ifndef AVUTIL_INTREADWRITE_H
20 #define AVUTIL_INTREADWRITE_H
21
22 #include <stdint.h>
23 #include "config.h"
24 #include "bswap.h"
25 #include "common.h"
26
27 typedef union {
28     uint64_t u64;
29     uint32_t u32[2];
30     uint16_t u16[4];
31     uint8_t  u8 [8];
32     double   f64;
33     float    f32[2];
34 } av_alias av_alias64;
35
36 typedef union {
37     uint32_t u32;
38     uint16_t u16[2];
39     uint8_t  u8 [4];
40     float    f32;
41 } av_alias av_alias32;
42
43 typedef union {
44     uint16_t u16;
45     uint8_t  u8 [2];
46 } av_alias av_alias16;
47
48 /*
49  * Arch-specific headers can provide any combination of
50  * AV_[RW][BLN](16|24|32|64) and AV_(COPY|SWAP|ZERO)(64|128) macros.
51  * Preprocessor symbols must be defined, even if these are implemented
52  * as inline functions.
53  */
54
55 #if   ARCH_ARM
56 #   include "arm/intreadwrite.h"
57 #elif ARCH_AVR32
58 #   include "avr32/intreadwrite.h"
59 #elif ARCH_MIPS
60 #   include "mips/intreadwrite.h"
61 #elif ARCH_PPC
62 #   include "ppc/intreadwrite.h"
63 #elif ARCH_X86
64 #   include "x86/intreadwrite.h"
65 #endif
66
67 /*
68  * Map AV_RNXX <-> AV_R[BL]XX for all variants provided by per-arch headers.
69  */
70
71 #if HAVE_BIGENDIAN
72
73 #   if    defined(AV_RN16) && !defined(AV_RB16)
74 #       define AV_RB16(p) AV_RN16(p)
75 #   elif !defined(AV_RN16) &&  defined(AV_RB16)
76 #       define AV_RN16(p) AV_RB16(p)
77 #   endif
78
79 #   if    defined(AV_WN16) && !defined(AV_WB16)
80 #       define AV_WB16(p, v) AV_WN16(p, v)
81 #   elif !defined(AV_WN16) &&  defined(AV_WB16)
82 #       define AV_WN16(p, v) AV_WB16(p, v)
83 #   endif
84
85 #   if    defined(AV_RN24) && !defined(AV_RB24)
86 #       define AV_RB24(p) AV_RN24(p)
87 #   elif !defined(AV_RN24) &&  defined(AV_RB24)
88 #       define AV_RN24(p) AV_RB24(p)
89 #   endif
90
91 #   if    defined(AV_WN24) && !defined(AV_WB24)
92 #       define AV_WB24(p, v) AV_WN24(p, v)
93 #   elif !defined(AV_WN24) &&  defined(AV_WB24)
94 #       define AV_WN24(p, v) AV_WB24(p, v)
95 #   endif
96
97 #   if    defined(AV_RN32) && !defined(AV_RB32)
98 #       define AV_RB32(p) AV_RN32(p)
99 #   elif !defined(AV_RN32) &&  defined(AV_RB32)
100 #       define AV_RN32(p) AV_RB32(p)
101 #   endif
102
103 #   if    defined(AV_WN32) && !defined(AV_WB32)
104 #       define AV_WB32(p, v) AV_WN32(p, v)
105 #   elif !defined(AV_WN32) &&  defined(AV_WB32)
106 #       define AV_WN32(p, v) AV_WB32(p, v)
107 #   endif
108
109 #   if    defined(AV_RN64) && !defined(AV_RB64)
110 #       define AV_RB64(p) AV_RN64(p)
111 #   elif !defined(AV_RN64) &&  defined(AV_RB64)
112 #       define AV_RN64(p) AV_RB64(p)
113 #   endif
114
115 #   if    defined(AV_WN64) && !defined(AV_WB64)
116 #       define AV_WB64(p, v) AV_WN64(p, v)
117 #   elif !defined(AV_WN64) &&  defined(AV_WB64)
118 #       define AV_WN64(p, v) AV_WB64(p, v)
119 #   endif
120
121 #else /* HAVE_BIGENDIAN */
122
123 #   if    defined(AV_RN16) && !defined(AV_RL16)
124 #       define AV_RL16(p) AV_RN16(p)
125 #   elif !defined(AV_RN16) &&  defined(AV_RL16)
126 #       define AV_RN16(p) AV_RL16(p)
127 #   endif
128
129 #   if    defined(AV_WN16) && !defined(AV_WL16)
130 #       define AV_WL16(p, v) AV_WN16(p, v)
131 #   elif !defined(AV_WN16) &&  defined(AV_WL16)
132 #       define AV_WN16(p, v) AV_WL16(p, v)
133 #   endif
134
135 #   if    defined(AV_RN24) && !defined(AV_RL24)
136 #       define AV_RL24(p) AV_RN24(p)
137 #   elif !defined(AV_RN24) &&  defined(AV_RL24)
138 #       define AV_RN24(p) AV_RL24(p)
139 #   endif
140
141 #   if    defined(AV_WN24) && !defined(AV_WL24)
142 #       define AV_WL24(p, v) AV_WN24(p, v)
143 #   elif !defined(AV_WN24) &&  defined(AV_WL24)
144 #       define AV_WN24(p, v) AV_WL24(p, v)
145 #   endif
146
147 #   if    defined(AV_RN32) && !defined(AV_RL32)
148 #       define AV_RL32(p) AV_RN32(p)
149 #   elif !defined(AV_RN32) &&  defined(AV_RL32)
150 #       define AV_RN32(p) AV_RL32(p)
151 #   endif
152
153 #   if    defined(AV_WN32) && !defined(AV_WL32)
154 #       define AV_WL32(p, v) AV_WN32(p, v)
155 #   elif !defined(AV_WN32) &&  defined(AV_WL32)
156 #       define AV_WN32(p, v) AV_WL32(p, v)
157 #   endif
158
159 #   if    defined(AV_RN64) && !defined(AV_RL64)
160 #       define AV_RL64(p) AV_RN64(p)
161 #   elif !defined(AV_RN64) &&  defined(AV_RL64)
162 #       define AV_RN64(p) AV_RL64(p)
163 #   endif
164
165 #   if    defined(AV_WN64) && !defined(AV_WL64)
166 #       define AV_WL64(p, v) AV_WN64(p, v)
167 #   elif !defined(AV_WN64) &&  defined(AV_WL64)
168 #       define AV_WN64(p, v) AV_WL64(p, v)
169 #   endif
170
171 #endif /* !HAVE_BIGENDIAN */
172
173 /*
174  * Define AV_[RW]N helper macros to simplify definitions not provided
175  * by per-arch headers.
176  */
177
178 #if   HAVE_ATTRIBUTE_PACKED
179
180 union unaligned_64 { uint64_t l; } __attribute__((packed)) av_alias;
181 union unaligned_32 { uint32_t l; } __attribute__((packed)) av_alias;
182 union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias;
183
184 #   define AV_RN(s, p) (((const union unaligned_##s *) (p))->l)
185 #   define AV_WN(s, p, v) ((((union unaligned_##s *) (p))->l) = (v))
186
187 #elif defined(__DECC)
188
189 #   define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p)))
190 #   define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v))
191
192 #elif HAVE_FAST_UNALIGNED
193
194 #   define AV_RN(s, p) (((const av_alias##s*)(p))->u##s)
195 #   define AV_WN(s, p, v) (((uint##s##_t*)(p))->u##s = (v))
196
197 #else
198
199 #ifndef AV_RB16
200 #   define AV_RB16(x)                           \
201     ((((const uint8_t*)(x))[0] << 8) |          \
202       ((const uint8_t*)(x))[1])
203 #endif
204 #ifndef AV_WB16
205 #   define AV_WB16(p, d) do {                   \
206         ((uint8_t*)(p))[1] = (d);               \
207         ((uint8_t*)(p))[0] = (d)>>8;            \
208     } while(0)
209 #endif
210
211 #ifndef AV_RL16
212 #   define AV_RL16(x)                           \
213     ((((const uint8_t*)(x))[1] << 8) |          \
214       ((const uint8_t*)(x))[0])
215 #endif
216 #ifndef AV_WL16
217 #   define AV_WL16(p, d) do {                   \
218         ((uint8_t*)(p))[0] = (d);               \
219         ((uint8_t*)(p))[1] = (d)>>8;            \
220     } while(0)
221 #endif
222
223 #ifndef AV_RB32
224 #   define AV_RB32(x)                           \
225     ((((const uint8_t*)(x))[0] << 24) |         \
226      (((const uint8_t*)(x))[1] << 16) |         \
227      (((const uint8_t*)(x))[2] <<  8) |         \
228       ((const uint8_t*)(x))[3])
229 #endif
230 #ifndef AV_WB32
231 #   define AV_WB32(p, d) do {                   \
232         ((uint8_t*)(p))[3] = (d);               \
233         ((uint8_t*)(p))[2] = (d)>>8;            \
234         ((uint8_t*)(p))[1] = (d)>>16;           \
235         ((uint8_t*)(p))[0] = (d)>>24;           \
236     } while(0)
237 #endif
238
239 #ifndef AV_RL32
240 #   define AV_RL32(x)                           \
241     ((((const uint8_t*)(x))[3] << 24) |         \
242      (((const uint8_t*)(x))[2] << 16) |         \
243      (((const uint8_t*)(x))[1] <<  8) |         \
244       ((const uint8_t*)(x))[0])
245 #endif
246 #ifndef AV_WL32
247 #   define AV_WL32(p, d) do {                   \
248         ((uint8_t*)(p))[0] = (d);               \
249         ((uint8_t*)(p))[1] = (d)>>8;            \
250         ((uint8_t*)(p))[2] = (d)>>16;           \
251         ((uint8_t*)(p))[3] = (d)>>24;           \
252     } while(0)
253 #endif
254
255 #ifndef AV_RB64
256 #   define AV_RB64(x)                                   \
257     (((uint64_t)((const uint8_t*)(x))[0] << 56) |       \
258      ((uint64_t)((const uint8_t*)(x))[1] << 48) |       \
259      ((uint64_t)((const uint8_t*)(x))[2] << 40) |       \
260      ((uint64_t)((const uint8_t*)(x))[3] << 32) |       \
261      ((uint64_t)((const uint8_t*)(x))[4] << 24) |       \
262      ((uint64_t)((const uint8_t*)(x))[5] << 16) |       \
263      ((uint64_t)((const uint8_t*)(x))[6] <<  8) |       \
264       (uint64_t)((const uint8_t*)(x))[7])
265 #endif
266 #ifndef AV_WB64
267 #   define AV_WB64(p, d) do {                   \
268         ((uint8_t*)(p))[7] = (d);               \
269         ((uint8_t*)(p))[6] = (d)>>8;            \
270         ((uint8_t*)(p))[5] = (d)>>16;           \
271         ((uint8_t*)(p))[4] = (d)>>24;           \
272         ((uint8_t*)(p))[3] = (d)>>32;           \
273         ((uint8_t*)(p))[2] = (d)>>40;           \
274         ((uint8_t*)(p))[1] = (d)>>48;           \
275         ((uint8_t*)(p))[0] = (d)>>56;           \
276     } while(0)
277 #endif
278
279 #ifndef AV_RL64
280 #   define AV_RL64(x)                                   \
281     (((uint64_t)((const uint8_t*)(x))[7] << 56) |       \
282      ((uint64_t)((const uint8_t*)(x))[6] << 48) |       \
283      ((uint64_t)((const uint8_t*)(x))[5] << 40) |       \
284      ((uint64_t)((const uint8_t*)(x))[4] << 32) |       \
285      ((uint64_t)((const uint8_t*)(x))[3] << 24) |       \
286      ((uint64_t)((const uint8_t*)(x))[2] << 16) |       \
287      ((uint64_t)((const uint8_t*)(x))[1] <<  8) |       \
288       (uint64_t)((const uint8_t*)(x))[0])
289 #endif
290 #ifndef AV_WL64
291 #   define AV_WL64(p, d) do {                   \
292         ((uint8_t*)(p))[0] = (d);               \
293         ((uint8_t*)(p))[1] = (d)>>8;            \
294         ((uint8_t*)(p))[2] = (d)>>16;           \
295         ((uint8_t*)(p))[3] = (d)>>24;           \
296         ((uint8_t*)(p))[4] = (d)>>32;           \
297         ((uint8_t*)(p))[5] = (d)>>40;           \
298         ((uint8_t*)(p))[6] = (d)>>48;           \
299         ((uint8_t*)(p))[7] = (d)>>56;           \
300     } while(0)
301 #endif
302
303 #if HAVE_BIGENDIAN
304 #   define AV_RN(s, p)    AV_RB##s(p)
305 #   define AV_WN(s, p, v) AV_WB##s(p, v)
306 #else
307 #   define AV_RN(s, p)    AV_RL##s(p)
308 #   define AV_WN(s, p, v) AV_WL##s(p, v)
309 #endif
310
311 #endif /* HAVE_FAST_UNALIGNED */
312
313 #ifndef AV_RN16
314 #   define AV_RN16(p) AV_RN(16, p)
315 #endif
316
317 #ifndef AV_RN32
318 #   define AV_RN32(p) AV_RN(32, p)
319 #endif
320
321 #ifndef AV_RN64
322 #   define AV_RN64(p) AV_RN(64, p)
323 #endif
324
325 #ifndef AV_WN16
326 #   define AV_WN16(p, v) AV_WN(16, p, v)
327 #endif
328
329 #ifndef AV_WN32
330 #   define AV_WN32(p, v) AV_WN(32, p, v)
331 #endif
332
333 #ifndef AV_WN64
334 #   define AV_WN64(p, v) AV_WN(64, p, v)
335 #endif
336
337 #if HAVE_BIGENDIAN
338 #   define AV_RB(s, p)    AV_RN##s(p)
339 #   define AV_WB(s, p, v) AV_WN##s(p, v)
340 #   define AV_RL(s, p)    bswap_##s(AV_RN##s(p))
341 #   define AV_WL(s, p, v) AV_WN##s(p, bswap_##s(v))
342 #else
343 #   define AV_RB(s, p)    bswap_##s(AV_RN##s(p))
344 #   define AV_WB(s, p, v) AV_WN##s(p, bswap_##s(v))
345 #   define AV_RL(s, p)    AV_RN##s(p)
346 #   define AV_WL(s, p, v) AV_WN##s(p, v)
347 #endif
348
349 #define AV_RB8(x)     (((const uint8_t*)(x))[0])
350 #define AV_WB8(p, d)  do { ((uint8_t*)(p))[0] = (d); } while(0)
351
352 #define AV_RL8(x)     AV_RB8(x)
353 #define AV_WL8(p, d)  AV_WB8(p, d)
354
355 #ifndef AV_RB16
356 #   define AV_RB16(p)    AV_RB(16, p)
357 #endif
358 #ifndef AV_WB16
359 #   define AV_WB16(p, v) AV_WB(16, p, v)
360 #endif
361
362 #ifndef AV_RL16
363 #   define AV_RL16(p)    AV_RL(16, p)
364 #endif
365 #ifndef AV_WL16
366 #   define AV_WL16(p, v) AV_WL(16, p, v)
367 #endif
368
369 #ifndef AV_RB32
370 #   define AV_RB32(p)    AV_RB(32, p)
371 #endif
372 #ifndef AV_WB32
373 #   define AV_WB32(p, v) AV_WB(32, p, v)
374 #endif
375
376 #ifndef AV_RL32
377 #   define AV_RL32(p)    AV_RL(32, p)
378 #endif
379 #ifndef AV_WL32
380 #   define AV_WL32(p, v) AV_WL(32, p, v)
381 #endif
382
383 #ifndef AV_RB64
384 #   define AV_RB64(p)    AV_RB(64, p)
385 #endif
386 #ifndef AV_WB64
387 #   define AV_WB64(p, v) AV_WB(64, p, v)
388 #endif
389
390 #ifndef AV_RL64
391 #   define AV_RL64(p)    AV_RL(64, p)
392 #endif
393 #ifndef AV_WL64
394 #   define AV_WL64(p, v) AV_WL(64, p, v)
395 #endif
396
397 #ifndef AV_RB24
398 #   define AV_RB24(x)                           \
399     ((((const uint8_t*)(x))[0] << 16) |         \
400      (((const uint8_t*)(x))[1] <<  8) |         \
401       ((const uint8_t*)(x))[2])
402 #endif
403 #ifndef AV_WB24
404 #   define AV_WB24(p, d) do {                   \
405         ((uint8_t*)(p))[2] = (d);               \
406         ((uint8_t*)(p))[1] = (d)>>8;            \
407         ((uint8_t*)(p))[0] = (d)>>16;           \
408     } while(0)
409 #endif
410
411 #ifndef AV_RL24
412 #   define AV_RL24(x)                           \
413     ((((const uint8_t*)(x))[2] << 16) |         \
414      (((const uint8_t*)(x))[1] <<  8) |         \
415       ((const uint8_t*)(x))[0])
416 #endif
417 #ifndef AV_WL24
418 #   define AV_WL24(p, d) do {                   \
419         ((uint8_t*)(p))[0] = (d);               \
420         ((uint8_t*)(p))[1] = (d)>>8;            \
421         ((uint8_t*)(p))[2] = (d)>>16;           \
422     } while(0)
423 #endif
424
425 /* Parameters for AV_COPY*, AV_SWAP*, AV_ZERO* must be
426  * naturally aligned. They may be implemented using MMX,
427  * so emms_c() must be called before using any float code
428  * afterwards.
429  */
430
431 #define AV_COPY(n, d, s) (*(uint##n##_t*)(d) = *(const uint##n##_t*)(s))
432
433 #ifndef AV_COPY32
434 #   define AV_COPY32(d, s) AV_COPY(32, d, s)
435 #endif
436
437 #ifndef AV_COPY64
438 #   define AV_COPY64(d, s) AV_COPY(64, d, s)
439 #endif
440
441 #ifndef AV_COPY128
442 #   define AV_COPY128(d, s)                    \
443     do {                                       \
444         AV_COPY64(d, s);                       \
445         AV_COPY64((char*)(d)+8, (char*)(s)+8); \
446     } while(0)
447 #endif
448
449 #define AV_SWAP(n, a, b) FFSWAP(uint##n##_t, *(uint##n##_t*)(a), *(uint##n##_t*)(b))
450
451 #ifndef AV_SWAP64
452 #   define AV_SWAP64(a, b) AV_SWAP(64, a, b)
453 #endif
454
455 #define AV_ZERO(n, d) (*(uint##n##_t*)(d) = 0)
456
457 #ifndef AV_ZERO64
458 #   define AV_ZERO64(d) AV_ZERO(64, d)
459 #endif
460
461 #ifndef AV_ZERO128
462 #   define AV_ZERO128(d)         \
463     do {                         \
464         AV_ZERO64(d);            \
465         AV_ZERO64((char*)(d)+8); \
466     } while(0)
467 #endif
468
469 #endif /* AVUTIL_INTREADWRITE_H */