PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
dicom_tag.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#pragma once
19
20#include <compare>
21#include <cstdint>
22#include <functional>
23#include <optional>
24#include <string>
25#include <string_view>
26#include <utility>
27
28namespace kcenon::pacs::core {
29
51class dicom_tag {
52public:
56 constexpr dicom_tag() noexcept : combined_{0} {}
57
63 constexpr dicom_tag(uint16_t group, uint16_t element) noexcept
64 : combined_{static_cast<uint32_t>(group) << 16 | element} {}
65
70 explicit constexpr dicom_tag(uint32_t combined) noexcept
72
83 [[nodiscard]] static auto from_string(std::string_view str)
84 -> std::optional<dicom_tag>;
85
90 [[nodiscard]] constexpr auto group() const noexcept -> uint16_t {
91 return static_cast<uint16_t>(combined_ >> 16);
92 }
93
98 [[nodiscard]] constexpr auto element() const noexcept -> uint16_t {
99 return static_cast<uint16_t>(combined_ & 0xFFFF);
100 }
101
106 [[nodiscard]] constexpr auto combined() const noexcept -> uint32_t {
107 return combined_;
108 }
109
119 [[nodiscard]] constexpr auto is_private() const noexcept -> bool {
120 const auto grp = group();
121 return (grp & 1) != 0 && grp > 0x0008;
122 }
123
128 [[nodiscard]] constexpr auto is_group_length() const noexcept -> bool {
129 return element() == 0x0000;
130 }
131
140 [[nodiscard]] constexpr auto is_private_creator() const noexcept -> bool {
141 if (!is_private()) {
142 return false;
143 }
144 const auto elem = element();
145 return elem >= 0x0010 && elem <= 0x00FF;
146 }
147
156 [[nodiscard]] constexpr auto is_private_data() const noexcept -> bool {
157 return is_private() && element() > 0x00FF;
158 }
159
169 [[nodiscard]] constexpr auto private_block_number() const noexcept
170 -> std::optional<uint8_t> {
171 if (!is_private_data()) {
172 return std::nullopt;
173 }
174 return static_cast<uint8_t>(element() >> 8);
175 }
176
186 [[nodiscard]] constexpr auto private_creator_tag() const noexcept
187 -> std::optional<dicom_tag> {
188 const auto block = private_block_number();
189 if (!block) {
190 return std::nullopt;
191 }
192 return dicom_tag{group(), *block};
193 }
194
203 [[nodiscard]] constexpr auto private_data_range() const noexcept
204 -> std::optional<std::pair<dicom_tag, dicom_tag>> {
205 if (!is_private_creator()) {
206 return std::nullopt;
207 }
208 const auto block = static_cast<uint16_t>(element() << 8);
209 return std::pair{
210 dicom_tag{group(), block},
211 dicom_tag{group(), static_cast<uint16_t>(block | 0x00FF)}
212 };
213 }
214
219 [[nodiscard]] auto to_string() const -> std::string;
220
227 [[nodiscard]] constexpr auto operator<=>(const dicom_tag& other) const noexcept
228 -> std::strong_ordering = default;
229
233 [[nodiscard]] constexpr auto operator==(const dicom_tag& other) const noexcept
234 -> bool = default;
235
236private:
237 uint32_t combined_;
238};
239
240} // namespace kcenon::pacs::core
241
242
243// Hash specialization for use in unordered containers
244template <>
245struct std::hash<kcenon::pacs::core::dicom_tag> {
246 [[nodiscard]] auto operator()(const kcenon::pacs::core::dicom_tag& tag) const noexcept
247 -> size_t {
248 return std::hash<uint32_t>{}(tag.combined());
249 }
250};
constexpr auto private_block_number() const noexcept -> std::optional< uint8_t >
Extract the Private Creator block number from this tag.
Definition dicom_tag.h:169
constexpr auto private_data_range() const noexcept -> std::optional< std::pair< dicom_tag, dicom_tag > >
Get the data element range owned by this Private Creator tag.
Definition dicom_tag.h:203
constexpr auto is_private() const noexcept -> bool
Check if this is a private tag.
Definition dicom_tag.h:119
constexpr auto is_group_length() const noexcept -> bool
Check if this is a group length tag (xxxx,0000)
Definition dicom_tag.h:128
static auto from_string(std::string_view str) -> std::optional< dicom_tag >
Parse tag from string representation.
Definition dicom_tag.cpp:58
constexpr auto is_private_creator() const noexcept -> bool
Check if this is a private creator tag.
Definition dicom_tag.h:140
constexpr dicom_tag(uint16_t group, uint16_t element) noexcept
Construct from group and element numbers.
Definition dicom_tag.h:63
constexpr auto private_creator_tag() const noexcept -> std::optional< dicom_tag >
Get the Private Creator tag that owns this data element.
Definition dicom_tag.h:186
auto to_string() const -> std::string
Convert to string representation.
constexpr dicom_tag(uint32_t combined) noexcept
Construct from combined 32-bit value.
Definition dicom_tag.h:70
constexpr auto group() const noexcept -> uint16_t
Get the group number.
Definition dicom_tag.h:90
constexpr auto is_private_data() const noexcept -> bool
Check if this is a private data element.
Definition dicom_tag.h:156
constexpr auto element() const noexcept -> uint16_t
Get the element number.
Definition dicom_tag.h:98
constexpr dicom_tag() noexcept
Default constructor - creates tag (0000,0000)
Definition dicom_tag.h:56
constexpr auto combined() const noexcept -> uint32_t
Get the combined 32-bit value.
Definition dicom_tag.h:106
auto operator()(const kcenon::pacs::core::dicom_tag &tag) const noexcept -> size_t
Definition dicom_tag.h:246