1/* 2 * This file is part of Libav. 3 * 4 * Libav 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 * Libav 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 Libav; 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 "libavutil/avconfig.h" 24#include "attributes.h" 25#include "bswap.h" 26 27typedef 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 36typedef union { 37 uint32_t u32; 38 uint16_t u16[2]; 39 uint8_t u8 [4]; 40 float f32; 41} av_alias av_alias32; 42 43typedef 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#ifdef HAVE_AV_CONFIG_H 56 57#include "config.h" 58 59#if ARCH_ARM 60# include "arm/intreadwrite.h" 61#elif ARCH_AVR32 62# include "avr32/intreadwrite.h" 63#elif ARCH_MIPS 64# include "mips/intreadwrite.h" 65#elif ARCH_PPC 66# include "ppc/intreadwrite.h" 67#elif ARCH_TOMI 68# include "tomi/intreadwrite.h" 69#elif ARCH_X86 70# include "x86/intreadwrite.h" 71#endif 72 73#endif /* HAVE_AV_CONFIG_H */ 74 75/* 76 * Map AV_RNXX <-> AV_R[BL]XX for all variants provided by per-arch headers. 77 */ 78 79#if AV_HAVE_BIGENDIAN 80 81# if defined(AV_RN16) && !defined(AV_RB16) 82# define AV_RB16(p) AV_RN16(p) 83# elif !defined(AV_RN16) && defined(AV_RB16) 84# define AV_RN16(p) AV_RB16(p) 85# endif 86 87# if defined(AV_WN16) && !defined(AV_WB16) 88# define AV_WB16(p, v) AV_WN16(p, v) 89# elif !defined(AV_WN16) && defined(AV_WB16) 90# define AV_WN16(p, v) AV_WB16(p, v) 91# endif 92 93# if defined(AV_RN24) && !defined(AV_RB24) 94# define AV_RB24(p) AV_RN24(p) 95# elif !defined(AV_RN24) && defined(AV_RB24) 96# define AV_RN24(p) AV_RB24(p) 97# endif 98 99# if defined(AV_WN24) && !defined(AV_WB24) 100# define AV_WB24(p, v) AV_WN24(p, v) 101# elif !defined(AV_WN24) && defined(AV_WB24) 102# define AV_WN24(p, v) AV_WB24(p, v) 103# endif 104 105# if defined(AV_RN32) && !defined(AV_RB32) 106# define AV_RB32(p) AV_RN32(p) 107# elif !defined(AV_RN32) && defined(AV_RB32) 108# define AV_RN32(p) AV_RB32(p) 109# endif 110 111# if defined(AV_WN32) && !defined(AV_WB32) 112# define AV_WB32(p, v) AV_WN32(p, v) 113# elif !defined(AV_WN32) && defined(AV_WB32) 114# define AV_WN32(p, v) AV_WB32(p, v) 115# endif 116 117# if defined(AV_RN64) && !defined(AV_RB64) 118# define AV_RB64(p) AV_RN64(p) 119# elif !defined(AV_RN64) && defined(AV_RB64) 120# define AV_RN64(p) AV_RB64(p) 121# endif 122 123# if defined(AV_WN64) && !defined(AV_WB64) 124# define AV_WB64(p, v) AV_WN64(p, v) 125# elif !defined(AV_WN64) && defined(AV_WB64) 126# define AV_WN64(p, v) AV_WB64(p, v) 127# endif 128 129#else /* AV_HAVE_BIGENDIAN */ 130 131# if defined(AV_RN16) && !defined(AV_RL16) 132# define AV_RL16(p) AV_RN16(p) 133# elif !defined(AV_RN16) && defined(AV_RL16) 134# define AV_RN16(p) AV_RL16(p) 135# endif 136 137# if defined(AV_WN16) && !defined(AV_WL16) 138# define AV_WL16(p, v) AV_WN16(p, v) 139# elif !defined(AV_WN16) && defined(AV_WL16) 140# define AV_WN16(p, v) AV_WL16(p, v) 141# endif 142 143# if defined(AV_RN24) && !defined(AV_RL24) 144# define AV_RL24(p) AV_RN24(p) 145# elif !defined(AV_RN24) && defined(AV_RL24) 146# define AV_RN24(p) AV_RL24(p) 147# endif 148 149# if defined(AV_WN24) && !defined(AV_WL24) 150# define AV_WL24(p, v) AV_WN24(p, v) 151# elif !defined(AV_WN24) && defined(AV_WL24) 152# define AV_WN24(p, v) AV_WL24(p, v) 153# endif 154 155# if defined(AV_RN32) && !defined(AV_RL32) 156# define AV_RL32(p) AV_RN32(p) 157# elif !defined(AV_RN32) && defined(AV_RL32) 158# define AV_RN32(p) AV_RL32(p) 159# endif 160 161# if defined(AV_WN32) && !defined(AV_WL32) 162# define AV_WL32(p, v) AV_WN32(p, v) 163# elif !defined(AV_WN32) && defined(AV_WL32) 164# define AV_WN32(p, v) AV_WL32(p, v) 165# endif 166 167# if defined(AV_RN64) && !defined(AV_RL64) 168# define AV_RL64(p) AV_RN64(p) 169# elif !defined(AV_RN64) && defined(AV_RL64) 170# define AV_RN64(p) AV_RL64(p) 171# endif 172 173# if defined(AV_WN64) && !defined(AV_WL64) 174# define AV_WL64(p, v) AV_WN64(p, v) 175# elif !defined(AV_WN64) && defined(AV_WL64) 176# define AV_WN64(p, v) AV_WL64(p, v) 177# endif 178 179#endif /* !AV_HAVE_BIGENDIAN */ 180 181/* 182 * Define AV_[RW]N helper macros to simplify definitions not provided 183 * by per-arch headers. 184 */ 185 186#if defined(__GNUC__) && !defined(__TI_COMPILER_VERSION__) 187 188union unaligned_64 { uint64_t l; } __attribute__((packed)) av_alias; 189union unaligned_32 { uint32_t l; } __attribute__((packed)) av_alias; 190union unaligned_16 { uint16_t l; } __attribute__((packed)) av_alias; 191 192# define AV_RN(s, p) (((const union unaligned_##s *) (p))->l) 193# define AV_WN(s, p, v) ((((union unaligned_##s *) (p))->l) = (v)) 194 195#elif defined(__DECC) 196 197# define AV_RN(s, p) (*((const __unaligned uint##s##_t*)(p))) 198# define AV_WN(s, p, v) (*((__unaligned uint##s##_t*)(p)) = (v)) 199 200#elif AV_HAVE_FAST_UNALIGNED 201 202# define AV_RN(s, p) (((const av_alias##s*)(p))->u##s) 203# define AV_WN(s, p, v) (((av_alias##s*)(p))->u##s = (v)) 204 205#else 206 207#ifndef AV_RB16 208# define AV_RB16(x) \ 209 ((((const uint8_t*)(x))[0] << 8) | \ 210 ((const uint8_t*)(x))[1]) 211#endif 212#ifndef AV_WB16 213# define AV_WB16(p, d) do { \ 214 ((uint8_t*)(p))[1] = (d); \ 215 ((uint8_t*)(p))[0] = (d)>>8; \ 216 } while(0) 217#endif 218 219#ifndef AV_RL16 220# define AV_RL16(x) \ 221 ((((const uint8_t*)(x))[1] << 8) | \ 222 ((const uint8_t*)(x))[0]) 223#endif 224#ifndef AV_WL16 225# define AV_WL16(p, d) do { \ 226 ((uint8_t*)(p))[0] = (d); \ 227 ((uint8_t*)(p))[1] = (d)>>8; \ 228 } while(0) 229#endif 230 231#ifndef AV_RB32 232# define AV_RB32(x) \ 233 (((uint32_t)((const uint8_t*)(x))[0] << 24) | \ 234 (((const uint8_t*)(x))[1] << 16) | \ 235 (((const uint8_t*)(x))[2] << 8) | \ 236 ((const uint8_t*)(x))[3]) 237#endif 238#ifndef AV_WB32 239# define AV_WB32(p, d) do { \ 240 ((uint8_t*)(p))[3] = (d); \ 241 ((uint8_t*)(p))[2] = (d)>>8; \ 242 ((uint8_t*)(p))[1] = (d)>>16; \ 243 ((uint8_t*)(p))[0] = (d)>>24; \ 244 } while(0) 245#endif 246 247#ifndef AV_RL32 248# define AV_RL32(x) \ 249 (((uint32_t)((const uint8_t*)(x))[3] << 24) | \ 250 (((const uint8_t*)(x))[2] << 16) | \ 251 (((const uint8_t*)(x))[1] << 8) | \ 252 ((const uint8_t*)(x))[0]) 253#endif 254#ifndef AV_WL32 255# define AV_WL32(p, d) do { \ 256 ((uint8_t*)(p))[0] = (d); \ 257 ((uint8_t*)(p))[1] = (d)>>8; \ 258 ((uint8_t*)(p))[2] = (d)>>16; \ 259 ((uint8_t*)(p))[3] = (d)>>24; \ 260 } while(0) 261#endif 262 263#ifndef AV_RB64 264# define AV_RB64(x) \ 265 (((uint64_t)((const uint8_t*)(x))[0] << 56) | \ 266 ((uint64_t)((const uint8_t*)(x))[1] << 48) | \ 267 ((uint64_t)((const uint8_t*)(x))[2] << 40) | \ 268 ((uint64_t)((const uint8_t*)(x))[3] << 32) | \ 269 ((uint64_t)((const uint8_t*)(x))[4] << 24) | \ 270 ((uint64_t)((const uint8_t*)(x))[5] << 16) | \ 271 ((uint64_t)((const uint8_t*)(x))[6] << 8) | \ 272 (uint64_t)((const uint8_t*)(x))[7]) 273#endif 274#ifndef AV_WB64 275# define AV_WB64(p, d) do { \ 276 ((uint8_t*)(p))[7] = (d); \ 277 ((uint8_t*)(p))[6] = (d)>>8; \ 278 ((uint8_t*)(p))[5] = (d)>>16; \ 279 ((uint8_t*)(p))[4] = (d)>>24; \ 280 ((uint8_t*)(p))[3] = (d)>>32; \ 281 ((uint8_t*)(p))[2] = (d)>>40; \ 282 ((uint8_t*)(p))[1] = (d)>>48; \ 283 ((uint8_t*)(p))[0] = (d)>>56; \ 284 } while(0) 285#endif 286 287#ifndef AV_RL64 288# define AV_RL64(x) \ 289 (((uint64_t)((const uint8_t*)(x))[7] << 56) | \ 290 ((uint64_t)((const uint8_t*)(x))[6] << 48) | \ 291 ((uint64_t)((const uint8_t*)(x))[5] << 40) | \ 292 ((uint64_t)((const uint8_t*)(x))[4] << 32) | \ 293 ((uint64_t)((const uint8_t*)(x))[3] << 24) | \ 294 ((uint64_t)((const uint8_t*)(x))[2] << 16) | \ 295 ((uint64_t)((const uint8_t*)(x))[1] << 8) | \ 296 (uint64_t)((const uint8_t*)(x))[0]) 297#endif 298#ifndef AV_WL64 299# define AV_WL64(p, d) do { \ 300 ((uint8_t*)(p))[0] = (d); \ 301 ((uint8_t*)(p))[1] = (d)>>8; \ 302 ((uint8_t*)(p))[2] = (d)>>16; \ 303 ((uint8_t*)(p))[3] = (d)>>24; \ 304 ((uint8_t*)(p))[4] = (d)>>32; \ 305 ((uint8_t*)(p))[5] = (d)>>40; \ 306 ((uint8_t*)(p))[6] = (d)>>48; \ 307 ((uint8_t*)(p))[7] = (d)>>56; \ 308 } while(0) 309#endif 310 311#if AV_HAVE_BIGENDIAN 312# define AV_RN(s, p) AV_RB##s(p) 313# define AV_WN(s, p, v) AV_WB##s(p, v) 314#else 315# define AV_RN(s, p) AV_RL##s(p) 316# define AV_WN(s, p, v) AV_WL##s(p, v) 317#endif 318 319#endif /* HAVE_FAST_UNALIGNED */ 320 321#ifndef AV_RN16 322# define AV_RN16(p) AV_RN(16, p) 323#endif 324 325#ifndef AV_RN32 326# define AV_RN32(p) AV_RN(32, p) 327#endif 328 329#ifndef AV_RN64 330# define AV_RN64(p) AV_RN(64, p) 331#endif 332 333#ifndef AV_WN16 334# define AV_WN16(p, v) AV_WN(16, p, v) 335#endif 336 337#ifndef AV_WN32 338# define AV_WN32(p, v) AV_WN(32, p, v) 339#endif 340 341#ifndef AV_WN64 342# define AV_WN64(p, v) AV_WN(64, p, v) 343#endif 344 345#if AV_HAVE_BIGENDIAN 346# define AV_RB(s, p) AV_RN##s(p) 347# define AV_WB(s, p, v) AV_WN##s(p, v) 348# define AV_RL(s, p) av_bswap##s(AV_RN##s(p)) 349# define AV_WL(s, p, v) AV_WN##s(p, av_bswap##s(v)) 350#else 351# define AV_RB(s, p) av_bswap##s(AV_RN##s(p)) 352# define AV_WB(s, p, v) AV_WN##s(p, av_bswap##s(v)) 353# define AV_RL(s, p) AV_RN##s(p) 354# define AV_WL(s, p, v) AV_WN##s(p, v) 355#endif 356 357#define AV_RB8(x) (((const uint8_t*)(x))[0]) 358#define AV_WB8(p, d) do { ((uint8_t*)(p))[0] = (d); } while(0) 359 360#define AV_RL8(x) AV_RB8(x) 361#define AV_WL8(p, d) AV_WB8(p, d) 362 363#ifndef AV_RB16 364# define AV_RB16(p) AV_RB(16, p) 365#endif 366#ifndef AV_WB16 367# define AV_WB16(p, v) AV_WB(16, p, v) 368#endif 369 370#ifndef AV_RL16 371# define AV_RL16(p) AV_RL(16, p) 372#endif 373#ifndef AV_WL16 374# define AV_WL16(p, v) AV_WL(16, p, v) 375#endif 376 377#ifndef AV_RB32 378# define AV_RB32(p) AV_RB(32, p) 379#endif 380#ifndef AV_WB32 381# define AV_WB32(p, v) AV_WB(32, p, v) 382#endif 383 384#ifndef AV_RL32 385# define AV_RL32(p) AV_RL(32, p) 386#endif 387#ifndef AV_WL32 388# define AV_WL32(p, v) AV_WL(32, p, v) 389#endif 390 391#ifndef AV_RB64 392# define AV_RB64(p) AV_RB(64, p) 393#endif 394#ifndef AV_WB64 395# define AV_WB64(p, v) AV_WB(64, p, v) 396#endif 397 398#ifndef AV_RL64 399# define AV_RL64(p) AV_RL(64, p) 400#endif 401#ifndef AV_WL64 402# define AV_WL64(p, v) AV_WL(64, p, v) 403#endif 404 405#ifndef AV_RB24 406# define AV_RB24(x) \ 407 ((((const uint8_t*)(x))[0] << 16) | \ 408 (((const uint8_t*)(x))[1] << 8) | \ 409 ((const uint8_t*)(x))[2]) 410#endif 411#ifndef AV_WB24 412# define AV_WB24(p, d) do { \ 413 ((uint8_t*)(p))[2] = (d); \ 414 ((uint8_t*)(p))[1] = (d)>>8; \ 415 ((uint8_t*)(p))[0] = (d)>>16; \ 416 } while(0) 417#endif 418 419#ifndef AV_RL24 420# define AV_RL24(x) \ 421 ((((const uint8_t*)(x))[2] << 16) | \ 422 (((const uint8_t*)(x))[1] << 8) | \ 423 ((const uint8_t*)(x))[0]) 424#endif 425#ifndef AV_WL24 426# define AV_WL24(p, d) do { \ 427 ((uint8_t*)(p))[0] = (d); \ 428 ((uint8_t*)(p))[1] = (d)>>8; \ 429 ((uint8_t*)(p))[2] = (d)>>16; \ 430 } while(0) 431#endif 432 433/* 434 * The AV_[RW]NA macros access naturally aligned data 435 * in a type-safe way. 436 */ 437 438#define AV_RNA(s, p) (((const av_alias##s*)(p))->u##s) 439#define AV_WNA(s, p, v) (((av_alias##s*)(p))->u##s = (v)) 440 441#ifndef AV_RN16A 442# define AV_RN16A(p) AV_RNA(16, p) 443#endif 444 445#ifndef AV_RN32A 446# define AV_RN32A(p) AV_RNA(32, p) 447#endif 448 449#ifndef AV_RN64A 450# define AV_RN64A(p) AV_RNA(64, p) 451#endif 452 453#ifndef AV_WN16A 454# define AV_WN16A(p, v) AV_WNA(16, p, v) 455#endif 456 457#ifndef AV_WN32A 458# define AV_WN32A(p, v) AV_WNA(32, p, v) 459#endif 460 461#ifndef AV_WN64A 462# define AV_WN64A(p, v) AV_WNA(64, p, v) 463#endif 464 465/* Parameters for AV_COPY*, AV_SWAP*, AV_ZERO* must be 466 * naturally aligned. They may be implemented using MMX, 467 * so emms_c() must be called before using any float code 468 * afterwards. 469 */ 470 471#define AV_COPY(n, d, s) \ 472 (((av_alias##n*)(d))->u##n = ((const av_alias##n*)(s))->u##n) 473 474#ifndef AV_COPY16 475# define AV_COPY16(d, s) AV_COPY(16, d, s) 476#endif 477 478#ifndef AV_COPY32 479# define AV_COPY32(d, s) AV_COPY(32, d, s) 480#endif 481 482#ifndef AV_COPY64 483# define AV_COPY64(d, s) AV_COPY(64, d, s) 484#endif 485 486#ifndef AV_COPY128 487# define AV_COPY128(d, s) \ 488 do { \ 489 AV_COPY64(d, s); \ 490 AV_COPY64((char*)(d)+8, (char*)(s)+8); \ 491 } while(0) 492#endif 493 494#define AV_SWAP(n, a, b) FFSWAP(av_alias##n, *(av_alias##n*)(a), *(av_alias##n*)(b)) 495 496#ifndef AV_SWAP64 497# define AV_SWAP64(a, b) AV_SWAP(64, a, b) 498#endif 499 500#define AV_ZERO(n, d) (((av_alias##n*)(d))->u##n = 0) 501 502#ifndef AV_ZERO16 503# define AV_ZERO16(d) AV_ZERO(16, d) 504#endif 505 506#ifndef AV_ZERO32 507# define AV_ZERO32(d) AV_ZERO(32, d) 508#endif 509 510#ifndef AV_ZERO64 511# define AV_ZERO64(d) AV_ZERO(64, d) 512#endif 513 514#ifndef AV_ZERO128 515# define AV_ZERO128(d) \ 516 do { \ 517 AV_ZERO64(d); \ 518 AV_ZERO64((char*)(d)+8); \ 519 } while(0) 520#endif 521 522#endif /* AVUTIL_INTREADWRITE_H */ 523