RawSpeed
fast raw decoding library
Loading...
Searching...
No Matches
Endianness.h
Go to the documentation of this file.
1/*
2 RawSpeed - RAW file decoder.
3
4 Copyright (C) 2009-2014 Klaus Post
5 Copyright (C) 2017 Axel Waggershauser
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20*/
21
22#pragma once
23
24#include <bit>
25#include <cassert>
26#include <cstdint>
27#include <cstring>
28
29namespace rawspeed {
30
31enum class Endianness : uint16_t {
32 little = 0xDEAD,
33 big = 0xBEEF,
34 unknown = 0x0BAD
35};
36
38 uint16_t testvar = 0xfeff;
39 uint32_t firstbyte = (reinterpret_cast<uint8_t*>(&testvar))[0];
40 if (firstbyte == 0xff)
41 return Endianness::little;
42 if (firstbyte == 0xfe)
43 return Endianness::big;
44
45 assert(false);
46
47 // Return something to make compilers happy
49}
50
52#if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
53 return Endianness::little;
54#elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
55 return Endianness::big;
56#elif defined(__BYTE_ORDER__)
57#error "uhm, __BYTE_ORDER__ has some strange value"
58#else
60#endif
61}
62
63#ifdef _MSC_VER
64#include <intrin.h>
65
66#define BSWAP16(A) _byteswap_ushort(A)
67#define BSWAP32(A) _byteswap_ulong(A)
68#define BSWAP64(A) _byteswap_uint64(A)
69#else
70#define BSWAP16(A) __builtin_bswap16(A)
71#define BSWAP32(A) __builtin_bswap32(A)
72#define BSWAP64(A) __builtin_bswap64(A)
73#endif
74
75inline int8_t getByteSwapped(int8_t v) { return v; }
76inline uint8_t getByteSwapped(uint8_t v) { return v; }
78 return static_cast<int16_t>(BSWAP16(static_cast<uint16_t>(v)));
79}
80inline uint16_t getByteSwapped(uint16_t v) { return BSWAP16(v); }
82 return static_cast<int32_t>(BSWAP32(static_cast<uint32_t>(v)));
83}
84inline uint32_t getByteSwapped(uint32_t v) { return BSWAP32(v); }
85inline uint64_t getByteSwapped(uint64_t v) { return BSWAP64(v); }
86
87// the float/double versions use two memcpy which guarantee strict aliasing
88// and are compiled into the same assembly as the popular union trick.
89inline float getByteSwapped(float f) {
90 auto i = std::bit_cast<uint32_t>(f);
91 i = getByteSwapped(i);
92 return std::bit_cast<float>(i);
93}
94inline double getByteSwapped(double d) {
95 auto i = std::bit_cast<uint64_t>(d);
96 i = getByteSwapped(i);
97 return std::bit_cast<double>(i);
98}
99
100template <typename T> inline T getByteSwapped(const void* data, bool bswap) {
101 T ret;
102 // all interesting compilers optimize this memcpy into a single move
103 // this is the most effective way to load some bytes without running into
104 // alignment or aliasing issues
105 memcpy(&ret, data, sizeof(T));
106 return bswap ? getByteSwapped(ret) : ret;
107}
108
109// The following functions may be used to get a multi-byte sized tyoe from some
110// memory location converted to the native byte order of the host.
111// 'BE' suffix: source byte order is known to be big endian
112// 'LE' suffix: source byte order is known to be little endian
113// Note: these functions should be avoided if higher level access from
114// Buffer/DataBuffer classes is available.
115
116template <typename T> inline T getBE(const void* data) {
118}
119
120template <typename T> inline T getLE(const void* data) {
122}
123
124inline uint16_t getU16BE(const void* data) { return getBE<uint16_t>(data); }
125inline uint16_t getU16LE(const void* data) { return getLE<uint16_t>(data); }
126inline uint32_t getU32BE(const void* data) { return getBE<uint32_t>(data); }
127inline uint32_t getU32LE(const void* data) { return getLE<uint32_t>(data); }
128
129#undef BSWAP64
130#undef BSWAP32
131#undef BSWAP16
132
133} // namespace rawspeed
#define BSWAP64(A)
Definition Endianness.h:72
#define BSWAP16(A)
Definition Endianness.h:70
#define BSWAP32(A)
Definition Endianness.h:71
assert(dim.area() >=area)
Endianness getHostEndiannessRuntime()
Definition Endianness.h:37
int8_t getByteSwapped(int8_t v)
Definition Endianness.h:75
uint16_t getU16LE(const void *data)
Definition Endianness.h:125
throw T(buf.data())
uint16_t getU16BE(const void *data)
Definition Endianness.h:124
Endianness getHostEndianness()
Definition Endianness.h:51
uint32_t getU32LE(const void *data)
Definition Endianness.h:127
uint32_t getU32BE(const void *data)
Definition Endianness.h:126
T getLE(const void *data)
Definition Endianness.h:120
T getBE(const void *data)
Definition Endianness.h:116