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 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 #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 188 union unaligned_64 { uint64_t l; } __attribute__((packed)) av_alias; 189 union unaligned_32 { uint32_t l; } __attribute__((packed)) av_alias; 190 union 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 /* 466 * The AV_COPYxxU macros are suitable for copying data to/from unaligned 467 * memory locations. 468 */ 469 470 #define AV_COPYU(n, d, s) AV_WN##n(d, AV_RN##n(s)); 471 472 #ifndef AV_COPY16U 473 # define AV_COPY16U(d, s) AV_COPYU(16, d, s) 474 #endif 475 476 #ifndef AV_COPY32U 477 # define AV_COPY32U(d, s) AV_COPYU(32, d, s) 478 #endif 479 480 #ifndef AV_COPY64U 481 # define AV_COPY64U(d, s) AV_COPYU(64, d, s) 482 #endif 483 484 #ifndef AV_COPY128U 485 # define AV_COPY128U(d, s) \ 486 do { \ 487 AV_COPY64U(d, s); \ 488 AV_COPY64U((char *)(d) + 8, (const char *)(s) + 8); \ 489 } while(0) 490 #endif 491 492 /* Parameters for AV_COPY*, AV_SWAP*, AV_ZERO* must be 493 * naturally aligned. They may be implemented using MMX, 494 * so emms_c() must be called before using any float code 495 * afterwards. 496 */ 497 498 #define AV_COPY(n, d, s) \ 499 (((av_alias##n*)(d))->u##n = ((const av_alias##n*)(s))->u##n) 500 501 #ifndef AV_COPY16 502 # define AV_COPY16(d, s) AV_COPY(16, d, s) 503 #endif 504 505 #ifndef AV_COPY32 506 # define AV_COPY32(d, s) AV_COPY(32, d, s) 507 #endif 508 509 #ifndef AV_COPY64 510 # define AV_COPY64(d, s) AV_COPY(64, d, s) 511 #endif 512 513 #ifndef AV_COPY128 514 # define AV_COPY128(d, s) \ 515 do { \ 516 AV_COPY64(d, s); \ 517 AV_COPY64((char*)(d)+8, (char*)(s)+8); \ 518 } while(0) 519 #endif 520 521 #define AV_SWAP(n, a, b) FFSWAP(av_alias##n, *(av_alias##n*)(a), *(av_alias##n*)(b)) 522 523 #ifndef AV_SWAP64 524 # define AV_SWAP64(a, b) AV_SWAP(64, a, b) 525 #endif 526 527 #define AV_ZERO(n, d) (((av_alias##n*)(d))->u##n = 0) 528 529 #ifndef AV_ZERO16 530 # define AV_ZERO16(d) AV_ZERO(16, d) 531 #endif 532 533 #ifndef AV_ZERO32 534 # define AV_ZERO32(d) AV_ZERO(32, d) 535 #endif 536 537 #ifndef AV_ZERO64 538 # define AV_ZERO64(d) AV_ZERO(64, d) 539 #endif 540 541 #ifndef AV_ZERO128 542 # define AV_ZERO128(d) \ 543 do { \ 544 AV_ZERO64(d); \ 545 AV_ZERO64((char*)(d)+8); \ 546 } while(0) 547 #endif 548 549 #endif /* AVUTIL_INTREADWRITE_H */ 550