PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
byte_swap.h
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
18#ifndef PACS_ENCODING_BYTE_SWAP_HPP
19#define PACS_ENCODING_BYTE_SWAP_HPP
20
21#include <cstdint>
22#include <cstring>
23#include <span>
24#include <vector>
25
26#include "simd/simd_utils.h"
27
28namespace kcenon::pacs::encoding {
29
32
40[[nodiscard]] constexpr uint16_t byte_swap16(uint16_t value) noexcept {
41 return static_cast<uint16_t>((value >> 8) | (value << 8));
42}
43
51[[nodiscard]] constexpr uint32_t byte_swap32(uint32_t value) noexcept {
52 return ((value >> 24) & 0x000000FF) |
53 ((value >> 8) & 0x0000FF00) |
54 ((value << 8) & 0x00FF0000) |
55 ((value << 24) & 0xFF000000);
56}
57
65[[nodiscard]] constexpr uint64_t byte_swap64(uint64_t value) noexcept {
66 return ((value >> 56) & 0x00000000000000FF) |
67 ((value >> 40) & 0x000000000000FF00) |
68 ((value >> 24) & 0x0000000000FF0000) |
69 ((value >> 8) & 0x00000000FF000000) |
70 ((value << 8) & 0x000000FF00000000) |
71 ((value << 24) & 0x0000FF0000000000) |
72 ((value << 40) & 0x00FF000000000000) |
73 ((value << 56) & 0xFF00000000000000);
74}
75
77
80
86[[nodiscard]] constexpr uint16_t read_be16(const uint8_t* data) noexcept {
87 return (static_cast<uint16_t>(data[0]) << 8) |
88 static_cast<uint16_t>(data[1]);
89}
90
96[[nodiscard]] constexpr uint32_t read_be32(const uint8_t* data) noexcept {
97 return (static_cast<uint32_t>(data[0]) << 24) |
98 (static_cast<uint32_t>(data[1]) << 16) |
99 (static_cast<uint32_t>(data[2]) << 8) |
100 static_cast<uint32_t>(data[3]);
101}
102
108[[nodiscard]] constexpr uint64_t read_be64(const uint8_t* data) noexcept {
109 return (static_cast<uint64_t>(data[0]) << 56) |
110 (static_cast<uint64_t>(data[1]) << 48) |
111 (static_cast<uint64_t>(data[2]) << 40) |
112 (static_cast<uint64_t>(data[3]) << 32) |
113 (static_cast<uint64_t>(data[4]) << 24) |
114 (static_cast<uint64_t>(data[5]) << 16) |
115 (static_cast<uint64_t>(data[6]) << 8) |
116 static_cast<uint64_t>(data[7]);
117}
118
124inline void write_be16(std::vector<uint8_t>& buffer, uint16_t value) {
125 buffer.push_back(static_cast<uint8_t>((value >> 8) & 0xFF));
126 buffer.push_back(static_cast<uint8_t>(value & 0xFF));
127}
128
134inline void write_be32(std::vector<uint8_t>& buffer, uint32_t value) {
135 buffer.push_back(static_cast<uint8_t>((value >> 24) & 0xFF));
136 buffer.push_back(static_cast<uint8_t>((value >> 16) & 0xFF));
137 buffer.push_back(static_cast<uint8_t>((value >> 8) & 0xFF));
138 buffer.push_back(static_cast<uint8_t>(value & 0xFF));
139}
140
146inline void write_be64(std::vector<uint8_t>& buffer, uint64_t value) {
147 buffer.push_back(static_cast<uint8_t>((value >> 56) & 0xFF));
148 buffer.push_back(static_cast<uint8_t>((value >> 48) & 0xFF));
149 buffer.push_back(static_cast<uint8_t>((value >> 40) & 0xFF));
150 buffer.push_back(static_cast<uint8_t>((value >> 32) & 0xFF));
151 buffer.push_back(static_cast<uint8_t>((value >> 24) & 0xFF));
152 buffer.push_back(static_cast<uint8_t>((value >> 16) & 0xFF));
153 buffer.push_back(static_cast<uint8_t>((value >> 8) & 0xFF));
154 buffer.push_back(static_cast<uint8_t>(value & 0xFF));
155}
156
158
161
170[[nodiscard]] inline std::vector<uint8_t> swap_ow_bytes(
171 std::span<const uint8_t> data) {
172 std::vector<uint8_t> result(data.size());
173 simd::swap_bytes_16_simd(data.data(), result.data(), data.size());
174 return result;
175}
176
185[[nodiscard]] inline std::vector<uint8_t> swap_ol_bytes(
186 std::span<const uint8_t> data) {
187 std::vector<uint8_t> result(data.size());
188 simd::swap_bytes_32_simd(data.data(), result.data(), data.size());
189 return result;
190}
191
199[[nodiscard]] inline std::vector<uint8_t> swap_of_bytes(
200 std::span<const uint8_t> data) {
201 return swap_ol_bytes(data); // Same as OL (32-bit values)
202}
203
212[[nodiscard]] inline std::vector<uint8_t> swap_od_bytes(
213 std::span<const uint8_t> data) {
214 std::vector<uint8_t> result(data.size());
215 simd::swap_bytes_64_simd(data.data(), result.data(), data.size());
216 return result;
217}
218
226[[nodiscard]] inline std::vector<uint8_t> swap_at_bytes(
227 std::span<const uint8_t> data) {
228 return swap_ow_bytes(data); // Each 16-bit part swapped individually
229}
230
232
235
241[[nodiscard]] inline std::vector<uint8_t> swap_us_bytes(
242 std::span<const uint8_t> data) {
243 return swap_ow_bytes(data);
244}
245
251[[nodiscard]] inline std::vector<uint8_t> swap_ss_bytes(
252 std::span<const uint8_t> data) {
253 return swap_ow_bytes(data);
254}
255
261[[nodiscard]] inline std::vector<uint8_t> swap_ul_bytes(
262 std::span<const uint8_t> data) {
263 return swap_ol_bytes(data);
264}
265
271[[nodiscard]] inline std::vector<uint8_t> swap_sl_bytes(
272 std::span<const uint8_t> data) {
273 return swap_ol_bytes(data);
274}
275
281[[nodiscard]] inline std::vector<uint8_t> swap_fl_bytes(
282 std::span<const uint8_t> data) {
283 return swap_ol_bytes(data);
284}
285
291[[nodiscard]] inline std::vector<uint8_t> swap_fd_bytes(
292 std::span<const uint8_t> data) {
293 return swap_od_bytes(data);
294}
295
297
298} // namespace kcenon::pacs::encoding
299
300#endif // PACS_ENCODING_BYTE_SWAP_HPP
void swap_bytes_32_simd(const uint8_t *src, uint8_t *dst, size_t count) noexcept
Swap bytes in 32-bit words using best available SIMD.
Definition simd_utils.h:312
void swap_bytes_64_simd(const uint8_t *src, uint8_t *dst, size_t count) noexcept
Swap bytes in 64-bit words using best available SIMD.
Definition simd_utils.h:346
void swap_bytes_16_simd(const uint8_t *src, uint8_t *dst, size_t count) noexcept
Swap bytes in 16-bit words using best available SIMD.
Definition simd_utils.h:278
std::vector< uint8_t > swap_fl_bytes(std::span< const uint8_t > data)
Swaps bytes for FL (Float) value in raw data.
Definition byte_swap.h:281
constexpr uint32_t read_be32(const uint8_t *data) noexcept
Reads a 32-bit value from big-endian bytes.
Definition byte_swap.h:96
constexpr uint64_t byte_swap64(uint64_t value) noexcept
Swaps bytes in a 64-bit value.
Definition byte_swap.h:65
std::vector< uint8_t > swap_ul_bytes(std::span< const uint8_t > data)
Swaps bytes for UL (Unsigned Long) value in raw data.
Definition byte_swap.h:261
constexpr uint32_t byte_swap32(uint32_t value) noexcept
Swaps bytes in a 32-bit value.
Definition byte_swap.h:51
std::vector< uint8_t > swap_od_bytes(std::span< const uint8_t > data)
Swaps bytes in-place for OD (Other Double) data.
Definition byte_swap.h:212
std::vector< uint8_t > swap_us_bytes(std::span< const uint8_t > data)
Swaps bytes for US (Unsigned Short) value in raw data.
Definition byte_swap.h:241
std::vector< uint8_t > swap_ow_bytes(std::span< const uint8_t > data)
Swaps bytes in-place for OW (Other Word) data.
Definition byte_swap.h:170
std::vector< uint8_t > swap_fd_bytes(std::span< const uint8_t > data)
Swaps bytes for FD (Double) value in raw data.
Definition byte_swap.h:291
void write_be64(std::vector< uint8_t > &buffer, uint64_t value)
Writes a 64-bit value in big-endian byte order.
Definition byte_swap.h:146
std::vector< uint8_t > swap_at_bytes(std::span< const uint8_t > data)
Swaps bytes for AT (Attribute Tag) data.
Definition byte_swap.h:226
void write_be32(std::vector< uint8_t > &buffer, uint32_t value)
Writes a 32-bit value in big-endian byte order.
Definition byte_swap.h:134
void write_be16(std::vector< uint8_t > &buffer, uint16_t value)
Writes a 16-bit value in big-endian byte order.
Definition byte_swap.h:124
std::vector< uint8_t > swap_sl_bytes(std::span< const uint8_t > data)
Swaps bytes for SL (Signed Long) value in raw data.
Definition byte_swap.h:271
constexpr uint16_t read_be16(const uint8_t *data) noexcept
Reads a 16-bit value from big-endian bytes.
Definition byte_swap.h:86
std::vector< uint8_t > swap_ss_bytes(std::span< const uint8_t > data)
Swaps bytes for SS (Signed Short) value in raw data.
Definition byte_swap.h:251
constexpr uint64_t read_be64(const uint8_t *data) noexcept
Reads a 64-bit value from big-endian bytes.
Definition byte_swap.h:108
constexpr uint16_t byte_swap16(uint16_t value) noexcept
Swaps bytes in a 16-bit value.
Definition byte_swap.h:40
std::vector< uint8_t > swap_ol_bytes(std::span< const uint8_t > data)
Swaps bytes in-place for OL (Other Long) data.
Definition byte_swap.h:185
std::vector< uint8_t > swap_of_bytes(std::span< const uint8_t > data)
Swaps bytes in-place for OF (Other Float) data.
Definition byte_swap.h:199
Common SIMD utility functions.