PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
us_storage.cpp
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
11
12#include <algorithm>
13#include <array>
14
16
17// =============================================================================
18// Transfer Syntaxes
19// =============================================================================
20
21std::vector<std::string> get_us_transfer_syntaxes() {
22 return {
23 // Explicit VR Little Endian (preferred for interoperability)
24 "1.2.840.10008.1.2.1",
25 // Implicit VR Little Endian (universal baseline)
26 "1.2.840.10008.1.2",
27 // JPEG Baseline (lossy, good for color US)
28 "1.2.840.10008.1.2.4.50",
29 // HTJ2K Lossless (high-throughput lossless)
30 "1.2.840.10008.1.2.4.201",
31 // JPEG Lossless (for diagnostic quality)
32 "1.2.840.10008.1.2.4.70",
33 // JPEG 2000 Lossless (better compression)
34 "1.2.840.10008.1.2.4.90",
35 // JPEG 2000 Lossy (for archival)
36 "1.2.840.10008.1.2.4.91",
37 // RLE Lossless
38 "1.2.840.10008.1.2.5"
39 };
40}
41
42// =============================================================================
43// Photometric Interpretation
44// =============================================================================
45
46namespace {
47
48constexpr std::string_view photometric_strings[] = {
49 "MONOCHROME1",
50 "MONOCHROME2",
51 "PALETTE COLOR",
52 "RGB",
53 "YBR_FULL",
54 "YBR_FULL_422"
55};
56
57} // namespace
58
59std::string_view to_string(us_photometric_interpretation interp) noexcept {
60 auto index = static_cast<size_t>(interp);
61 if (index < std::size(photometric_strings)) {
62 return photometric_strings[index];
63 }
64 return "MONOCHROME2";
65}
66
68parse_photometric_interpretation(std::string_view value) noexcept {
69 if (value == "MONOCHROME1") {
71 }
72 if (value == "MONOCHROME2") {
74 }
75 if (value == "PALETTE COLOR") {
77 }
78 if (value == "RGB") {
80 }
81 if (value == "YBR_FULL") {
83 }
84 if (value == "YBR_FULL_422") {
86 }
87 // Default to MONOCHROME2 for unknown values
89}
90
91bool is_valid_us_photometric(std::string_view value) noexcept {
92 return value == "MONOCHROME1" ||
93 value == "MONOCHROME2" ||
94 value == "PALETTE COLOR" ||
95 value == "RGB" ||
96 value == "YBR_FULL" ||
97 value == "YBR_FULL_422";
98}
99
100// =============================================================================
101// SOP Class Information
102// =============================================================================
103
104namespace {
105
106// Static array of US SOP class information
107constexpr std::array<us_sop_class_info, 4> us_sop_classes = {{
108 {
110 "US Image Storage",
111 "Single-frame ultrasound images",
112 false,
113 false
114 },
115 {
117 "US Multi-frame Image Storage",
118 "Multi-frame ultrasound cine loops and 3D/4D volumes",
119 false,
120 true
121 },
122 {
124 "US Image Storage (Retired)",
125 "Legacy single-frame ultrasound (retired)",
126 true,
127 false
128 },
129 {
131 "US Multi-frame Image Storage (Retired)",
132 "Legacy multi-frame ultrasound (retired)",
133 true,
134 true
135 }
136}};
137
138} // namespace
139
140std::vector<std::string> get_us_storage_sop_classes(bool include_retired) {
141 std::vector<std::string> result;
142 result.reserve(include_retired ? 4 : 2);
143
144 for (const auto& info : us_sop_classes) {
145 if (!info.is_retired || include_retired) {
146 result.emplace_back(info.uid);
147 }
148 }
149
150 return result;
151}
152
153const us_sop_class_info*
154get_us_sop_class_info(std::string_view uid) noexcept {
155 auto it = std::find_if(
156 us_sop_classes.begin(),
157 us_sop_classes.end(),
158 [uid](const auto& info) { return info.uid == uid; }
159 );
160
161 if (it != us_sop_classes.end()) {
162 return &(*it);
163 }
164 return nullptr;
165}
166
167bool is_us_storage_sop_class(std::string_view uid) noexcept {
168 return get_us_sop_class_info(uid) != nullptr;
169}
170
171bool is_us_multiframe_sop_class(std::string_view uid) noexcept {
172 const auto* info = get_us_sop_class_info(uid);
173 return info != nullptr && info->supports_multiframe;
174}
175
176} // namespace kcenon::pacs::services::sop_classes
us_photometric_interpretation parse_photometric_interpretation(std::string_view value) noexcept
Parse DICOM photometric interpretation string.
const us_sop_class_info * get_us_sop_class_info(std::string_view uid) noexcept
Get information about a specific US SOP Class.
bool is_us_multiframe_sop_class(std::string_view uid) noexcept
Check if a SOP Class UID is a multi-frame US Storage SOP Class.
bool is_us_storage_sop_class(std::string_view uid) noexcept
Check if a SOP Class UID is a US Storage SOP Class.
constexpr std::string_view us_image_storage_uid
US Image Storage SOP Class UID (single-frame)
Definition us_storage.h:39
constexpr std::string_view us_image_storage_retired_uid
US Image Storage (Retired) - for legacy systems.
Definition us_storage.h:52
bool is_valid_us_photometric(std::string_view value) noexcept
Check if photometric interpretation is valid for US.
us_photometric_interpretation
Supported photometric interpretations for US images.
Definition us_storage.h:83
std::vector< std::string > get_us_storage_sop_classes(bool include_retired=true)
Get all US Storage SOP Class UIDs.
constexpr std::string_view us_multiframe_image_storage_uid
US Multi-frame Image Storage SOP Class UID (cine loops)
Definition us_storage.h:43
constexpr std::string_view us_multiframe_image_storage_retired_uid
US Multi-frame Image Storage (Retired) - for legacy systems.
Definition us_storage.h:56
std::string_view to_string(dx_photometric_interpretation interp) noexcept
Convert photometric interpretation enum to DICOM string.
std::vector< std::string > get_us_transfer_syntaxes()
Get recommended transfer syntaxes for US images.
std::string_view uid
Ultrasound Image Storage SOP Classes.