60f02c7684e8a1fdf06aaedbd0657cefef5e359d
[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 INTREADWRITE_H
20 #define INTREADWRITE_H
21
22 #ifdef __GNUC__
23
24 struct unaligned_64 { uint64_t l; } __attribute__((packed));
25 struct unaligned_32 { uint32_t l; } __attribute__((packed));
26 struct unaligned_16 { uint16_t l; } __attribute__((packed));
27
28 #define LD16(a) (((const struct unaligned_16 *) (a))->l)
29 #define LD32(a) (((const struct unaligned_32 *) (a))->l)
30 #define LD64(a) (((const struct unaligned_64 *) (a))->l)
31
32 #define ST16(a, b) (((struct unaligned_16 *) (a))->l) = (b)
33 #define ST32(a, b) (((struct unaligned_32 *) (a))->l) = (b)
34 #define ST64(a, b) (((struct unaligned_64 *) (a))->l) = (b)
35
36 #else /* __GNUC__ */
37
38 #define LD16(a) (*((uint16_t*)(a)))
39 #define LD32(a) (*((uint32_t*)(a)))
40 #define LD64(a) (*((uint64_t*)(a)))
41
42 #define ST16(a, b) *((uint16_t*)(a)) = (b)
43 #define ST32(a, b) *((uint32_t*)(a)) = (b)
44 #define ST64(a, b) *((uint64_t*)(a)) = (b)
45
46 #endif /* !__GNUC__ */
47
48 /* endian macros */
49 #define AV_RB8(x)     (((uint8_t*)(x))[0])
50 #define AV_WB8(p, d)  { ((uint8_t*)(p))[0] = (d); }
51
52 #define AV_RL8(x)     AV_RB8(x)
53 #define AV_WL8(p, d)  AV_WB8(p, d)
54
55 #ifdef HAVE_FAST_UNALIGNED
56 # ifdef WORDS_BIGENDIAN
57 #  define AV_RB16(x)    LD16(x)
58 #  define AV_WB16(p, d) ST16(p, d)
59
60 #  define AV_RL16(x)    bswap_16(LD16(x))
61 #  define AV_WL16(p, d) ST16(p, bswap_16(d))
62 # else /* WORDS_BIGENDIAN */
63 #  define AV_RB16(x)    bswap_16(LD16(x))
64 #  define AV_WB16(p, d) ST16(p, bswap_16(d))
65
66 #  define AV_RL16(x)    LD16(x)
67 #  define AV_WL16(p, d) ST16(p, d)
68 # endif
69 #else /* HAVE_FAST_UNALIGNED */
70 #define AV_RB16(x)  ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
71 #define AV_WB16(p, d) { \
72                     ((uint8_t*)(p))[1] = (d); \
73                     ((uint8_t*)(p))[0] = (d)>>8; }
74
75 #define AV_RL16(x)  ((((uint8_t*)(x))[1] << 8) | \
76                       ((uint8_t*)(x))[0])
77 #define AV_WL16(p, d) { \
78                     ((uint8_t*)(p))[0] = (d); \
79                     ((uint8_t*)(p))[1] = (d)>>8; }
80 #endif
81
82 #define AV_RB24(x)  ((((uint8_t*)(x))[0] << 16) | \
83                      (((uint8_t*)(x))[1] <<  8) | \
84                       ((uint8_t*)(x))[2])
85 #define AV_WB24(p, d) { \
86                     ((uint8_t*)(p))[2] = (d); \
87                     ((uint8_t*)(p))[1] = (d)>>8; \
88                     ((uint8_t*)(p))[0] = (d)>>16; }
89
90 #define AV_RL24(x)  ((((uint8_t*)(x))[2] << 16) | \
91                      (((uint8_t*)(x))[1] <<  8) | \
92                       ((uint8_t*)(x))[0])
93 #define AV_WL24(p, d) { \
94                     ((uint8_t*)(p))[0] = (d); \
95                     ((uint8_t*)(p))[1] = (d)>>8; \
96                     ((uint8_t*)(p))[2] = (d)>>16; }
97
98 #ifdef HAVE_FAST_UNALIGNED
99 # ifdef WORDS_BIGENDIAN
100 #  define AV_RB32(x)    LD32(x)
101 #  define AV_WB32(p, d) ST32(p, d)
102
103 #  define AV_RL32(x)    bswap_32(LD32(x))
104 #  define AV_WL32(p, d) ST32(p, bswap_32(d))
105 # else /* WORDS_BIGENDIAN */
106 #  define AV_RB32(x)    bswap_32(LD32(x))
107 #  define AV_WB32(p, d) ST32(p, bswap_32(d))
108
109 #  define AV_RL32(x)    LD32(x)
110 #  define AV_WL32(p, d) ST32(p, d)
111 # endif
112 #else /* HAVE_FAST_UNALIGNED */
113 #define AV_RB32(x)  ((((uint8_t*)(x))[0] << 24) | \
114                      (((uint8_t*)(x))[1] << 16) | \
115                      (((uint8_t*)(x))[2] <<  8) | \
116                       ((uint8_t*)(x))[3])
117 #define AV_WB32(p, d) { \
118                     ((uint8_t*)(p))[3] = (d); \
119                     ((uint8_t*)(p))[2] = (d)>>8; \
120                     ((uint8_t*)(p))[1] = (d)>>16; \
121                     ((uint8_t*)(p))[0] = (d)>>24; }
122
123 #define AV_RL32(x) ((((uint8_t*)(x))[3] << 24) | \
124                     (((uint8_t*)(x))[2] << 16) | \
125                     (((uint8_t*)(x))[1] <<  8) | \
126                      ((uint8_t*)(x))[0])
127 #define AV_WL32(p, d) { \
128                     ((uint8_t*)(p))[0] = (d); \
129                     ((uint8_t*)(p))[1] = (d)>>8; \
130                     ((uint8_t*)(p))[2] = (d)>>16; \
131                     ((uint8_t*)(p))[3] = (d)>>24; }
132 #endif
133
134 #ifdef HAVE_FAST_UNALIGNED
135 # ifdef WORDS_BIGENDIAN
136 #  define AV_RB64(x)    LD64(x)
137 #  define AV_WB64(p, d) ST64(p, d)
138
139 #  define AV_RL64(x)    bswap_64(LD64(x))
140 #  define AV_WL64(p, d) ST64(p, bswap_64(d))
141 # else /* WORDS_BIGENDIAN */
142 #  define AV_RB64(x)    bswap_64(LD64(x))
143 #  define AV_WB64(p, d) ST64(p, bswap_64(d))
144
145 #  define AV_RL64(x)    LD64(x)
146 #  define AV_WL64(p, d) ST64(p, d)
147 # endif
148 #else /* HAVE_FAST_UNALIGNED */
149 #define AV_RB64(x)  (((uint64_t)((uint8_t*)(x))[0] << 56) | \
150                      ((uint64_t)((uint8_t*)(x))[1] << 48) | \
151                      ((uint64_t)((uint8_t*)(x))[2] << 40) | \
152                      ((uint64_t)((uint8_t*)(x))[3] << 32) | \
153                      ((uint64_t)((uint8_t*)(x))[4] << 24) | \
154                      ((uint64_t)((uint8_t*)(x))[5] << 16) | \
155                      ((uint64_t)((uint8_t*)(x))[6] <<  8) | \
156                       (uint64_t)((uint8_t*)(x))[7])
157 #define AV_WB64(p, d) { \
158                     ((uint8_t*)(p))[7] = (d);     \
159                     ((uint8_t*)(p))[6] = (d)>>8;  \
160                     ((uint8_t*)(p))[5] = (d)>>16; \
161                     ((uint8_t*)(p))[4] = (d)>>24; \
162                     ((uint8_t*)(p))[3] = (d)>>32; \
163                     ((uint8_t*)(p))[2] = (d)>>40; \
164                     ((uint8_t*)(p))[1] = (d)>>48; \
165                     ((uint8_t*)(p))[0] = (d)>>56; }
166
167 #define AV_RL64(x)  (((uint64_t)((uint8_t*)(x))[7] << 56) | \
168                      ((uint64_t)((uint8_t*)(x))[6] << 48) | \
169                      ((uint64_t)((uint8_t*)(x))[5] << 40) | \
170                      ((uint64_t)((uint8_t*)(x))[4] << 32) | \
171                      ((uint64_t)((uint8_t*)(x))[3] << 24) | \
172                      ((uint64_t)((uint8_t*)(x))[2] << 16) | \
173                      ((uint64_t)((uint8_t*)(x))[1] <<  8) | \
174                       (uint64_t)((uint8_t*)(x))[0])
175 #define AV_WL64(p, d) { \
176                     ((uint8_t*)(p))[0] = (d);     \
177                     ((uint8_t*)(p))[1] = (d)>>8;  \
178                     ((uint8_t*)(p))[2] = (d)>>16; \
179                     ((uint8_t*)(p))[3] = (d)>>24; \
180                     ((uint8_t*)(p))[4] = (d)>>32; \
181                     ((uint8_t*)(p))[5] = (d)>>40; \
182                     ((uint8_t*)(p))[6] = (d)>>48; \
183                     ((uint8_t*)(p))[7] = (d)>>56; }
184 #endif
185
186 #endif /* INTREADWRITE_H */