PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
transfer_syntax.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
6
7#include <algorithm>
8#include <array>
9
10namespace kcenon::pacs::encoding {
11
12namespace {
13
19struct ts_entry {
20 std::string_view uid;
21 std::string_view name;
22 byte_order endian;
23 vr_encoding vr;
26 bool supported; // Phase 1: only uncompressed syntaxes
27};
28
35static constexpr std::array<ts_entry, 18> TS_REGISTRY = {{
36 // Uncompressed Transfer Syntaxes (supported in Phase 1)
37 {"1.2.840.10008.1.2",
38 "Implicit VR Little Endian",
41 false, false, true},
42
43 {"1.2.840.10008.1.2.1",
44 "Explicit VR Little Endian",
47 false, false, true},
48
49 {"1.2.840.10008.1.2.2",
50 "Explicit VR Big Endian",
53 false, false, true},
54
55 // Deflated (not supported in Phase 1)
56 {"1.2.840.10008.1.2.1.99",
57 "Deflated Explicit VR Little Endian",
60 false, true, false},
61
62 // JPEG Transfer Syntaxes
63 {"1.2.840.10008.1.2.4.50",
64 "JPEG Baseline (Process 1)",
67 true, false, true}, // Supported in Phase 3
68
69 {"1.2.840.10008.1.2.4.70",
70 "JPEG Lossless, Non-Hierarchical, First-Order Prediction",
73 true, false, false},
74
75 // JPEG 2000 Transfer Syntaxes (not supported in Phase 1)
76 {"1.2.840.10008.1.2.4.90",
77 "JPEG 2000 Image Compression (Lossless Only)",
80 true, false, false},
81
82 {"1.2.840.10008.1.2.4.91",
83 "JPEG 2000 Image Compression",
86 true, false, false},
87
88 // RLE Lossless Transfer Syntax
89 {"1.2.840.10008.1.2.5",
90 "RLE Lossless",
93 true, false, true},
94
95 // High-Throughput JPEG 2000 Transfer Syntaxes (DICOM Supplement 235)
96 {"1.2.840.10008.1.2.4.201",
97 "High-Throughput JPEG 2000 Image Compression (Lossless Only)",
100 true, false, true},
101
102 {"1.2.840.10008.1.2.4.202",
103 "High-Throughput JPEG 2000 with RPCL Options Image Compression (Lossless Only)",
106 true, false, true},
107
108 {"1.2.840.10008.1.2.4.203",
109 "High-Throughput JPEG 2000 Image Compression",
112 true, false, true},
113
114 // HEVC/H.265 Transfer Syntaxes
115 {"1.2.840.10008.1.2.4.107",
116 "HEVC/H.265 Main Profile / Level 5.1",
119 true, false, true},
120
121 {"1.2.840.10008.1.2.4.108",
122 "HEVC/H.265 Main 10 Profile / Level 5.1",
125 true, false, true},
126
127 // JPEG XL Transfer Syntaxes (DICOM Supplement 232)
128 {"1.2.840.10008.1.2.4.110",
129 "JPEG XL Lossless",
132 true, false, true},
133
134 {"1.2.840.10008.1.2.4.111",
135 "JPEG XL JPEG Recompression",
138 true, false, true},
139
140 {"1.2.840.10008.1.2.4.112",
141 "JPEG XL",
144 true, false, true},
145
146 // Frame Deflate Transfer Syntax (DICOM Supplement 244)
147 {"1.2.840.10008.1.2.11",
148 "Frame Deflate",
151 true, false, true},
152}};
153
159const ts_entry* find_entry(std::string_view uid) {
160 auto it = std::find_if(TS_REGISTRY.begin(), TS_REGISTRY.end(),
161 [&uid](const ts_entry& entry) {
162 return entry.uid == uid;
163 });
164 return (it != TS_REGISTRY.end()) ? &(*it) : nullptr;
165}
166
167} // namespace
168
169// Static Transfer Syntax instances
171 "1.2.840.10008.1.2",
172 "Implicit VR Little Endian",
175 false, false, true};
176
178 "1.2.840.10008.1.2.1",
179 "Explicit VR Little Endian",
182 false, false, true};
183
184const transfer_syntax transfer_syntax::explicit_vr_big_endian{
185 "1.2.840.10008.1.2.2",
186 "Explicit VR Big Endian",
189 false, false, true};
190
191const transfer_syntax transfer_syntax::deflated_explicit_vr_le{
192 "1.2.840.10008.1.2.1.99",
193 "Deflated Explicit VR Little Endian",
196 false, true, false};
197
198const transfer_syntax transfer_syntax::jpeg_baseline{
199 "1.2.840.10008.1.2.4.50",
200 "JPEG Baseline (Process 1)",
203 true, false, true}; // Supported in Phase 3
204
205const transfer_syntax transfer_syntax::jpeg_lossless{
206 "1.2.840.10008.1.2.4.70",
207 "JPEG Lossless, Non-Hierarchical, First-Order Prediction",
210 true, false, false};
211
212const transfer_syntax transfer_syntax::jpeg2000_lossless{
213 "1.2.840.10008.1.2.4.90",
214 "JPEG 2000 Image Compression (Lossless Only)",
217 true, false, false};
218
219const transfer_syntax transfer_syntax::jpeg2000_lossy{
220 "1.2.840.10008.1.2.4.91",
221 "JPEG 2000 Image Compression",
224 true, false, false};
225
226const transfer_syntax transfer_syntax::rle_lossless{
227 "1.2.840.10008.1.2.5",
228 "RLE Lossless",
231 true, false, true};
232
233const transfer_syntax transfer_syntax::htj2k_lossless{
234 "1.2.840.10008.1.2.4.201",
235 "High-Throughput JPEG 2000 Image Compression (Lossless Only)",
238 true, false, true};
239
240const transfer_syntax transfer_syntax::htj2k_rpcl{
241 "1.2.840.10008.1.2.4.202",
242 "High-Throughput JPEG 2000 with RPCL Options Image Compression (Lossless Only)",
245 true, false, true};
246
247const transfer_syntax transfer_syntax::htj2k_lossy{
248 "1.2.840.10008.1.2.4.203",
249 "High-Throughput JPEG 2000 Image Compression",
252 true, false, true};
253
254const transfer_syntax transfer_syntax::hevc_main{
255 "1.2.840.10008.1.2.4.107",
256 "HEVC/H.265 Main Profile / Level 5.1",
259 true, false, true};
260
261const transfer_syntax transfer_syntax::hevc_main10{
262 "1.2.840.10008.1.2.4.108",
263 "HEVC/H.265 Main 10 Profile / Level 5.1",
266 true, false, true};
267
268const transfer_syntax transfer_syntax::jpegxl_lossless{
269 "1.2.840.10008.1.2.4.110",
270 "JPEG XL Lossless",
273 true, false, true};
274
276 "1.2.840.10008.1.2.4.111",
277 "JPEG XL JPEG Recompression",
280 true, false, true};
281
282const transfer_syntax transfer_syntax::jpegxl_lossy{
283 "1.2.840.10008.1.2.4.112",
284 "JPEG XL",
287 true, false, true};
288
289const transfer_syntax transfer_syntax::frame_deflate{
290 "1.2.840.10008.1.2.11",
291 "Frame Deflate",
294 true, false, true};
295
296// Public constructor - looks up UID in registry
298 : uid_(uid),
299 name_("Unknown"),
300 endianness_(byte_order::little_endian),
301 vr_type_(vr_encoding::implicit),
302 encapsulated_(false),
303 deflated_(false),
304 valid_(false),
305 supported_(false) {
306 if (const auto* entry = find_entry(uid)) {
307 name_ = entry->name;
308 endianness_ = entry->endian;
309 vr_type_ = entry->vr;
310 encapsulated_ = entry->encapsulated;
311 deflated_ = entry->deflated;
312 valid_ = true;
313 supported_ = entry->supported;
314 }
315}
316
317// Private constructor for static instances
318transfer_syntax::transfer_syntax(std::string_view uid, std::string_view name,
320 bool encapsulated, bool deflated,
321 bool supported)
322 : uid_(uid),
323 name_(name),
324 endianness_(endian),
325 vr_type_(vr),
326 encapsulated_(encapsulated),
327 deflated_(deflated),
328 valid_(true),
329 supported_(supported) {}
330
331std::string_view transfer_syntax::uid() const noexcept {
332 return uid_;
333}
334
335std::string_view transfer_syntax::name() const noexcept {
336 return name_;
337}
338
340 return endianness_;
341}
342
344 return vr_type_;
345}
346
347bool transfer_syntax::is_encapsulated() const noexcept {
348 return encapsulated_;
349}
350
351bool transfer_syntax::is_deflated() const noexcept {
352 return deflated_;
353}
354
355bool transfer_syntax::is_valid() const noexcept {
356 return valid_;
357}
358
359bool transfer_syntax::is_supported() const noexcept {
360 return supported_;
361}
362
363bool transfer_syntax::operator==(const transfer_syntax& other) const noexcept {
364 return uid_ == other.uid_;
365}
366
367bool transfer_syntax::operator!=(const transfer_syntax& other) const noexcept {
368 return !(*this == other);
369}
370
371std::optional<transfer_syntax> find_transfer_syntax(std::string_view uid) {
372 if (const auto* entry = find_entry(uid)) {
373 return transfer_syntax{entry->uid, entry->name, entry->endian,
374 entry->vr, entry->encapsulated, entry->deflated,
375 entry->supported};
376 }
377 return std::nullopt;
378}
379
380std::vector<transfer_syntax> supported_transfer_syntaxes() {
381 std::vector<transfer_syntax> result;
382 result.reserve(TS_REGISTRY.size());
383
384 for (const auto& entry : TS_REGISTRY) {
385 if (entry.supported) {
386 result.push_back(transfer_syntax{entry.uid, entry.name, entry.endian,
387 entry.vr, entry.encapsulated,
388 entry.deflated, entry.supported});
389 }
390 }
391 return result;
392}
393
394std::vector<transfer_syntax> all_transfer_syntaxes() {
395 std::vector<transfer_syntax> result;
396 result.reserve(TS_REGISTRY.size());
397
398 for (const auto& entry : TS_REGISTRY) {
399 result.push_back(transfer_syntax{entry.uid, entry.name, entry.endian,
400 entry.vr, entry.encapsulated,
401 entry.deflated, entry.supported});
402 }
403 return result;
404}
405
406} // namespace kcenon::pacs::encoding
Represents a DICOM Transfer Syntax.
vr_encoding vr_type() const noexcept
Returns the VR encoding mode for this Transfer Syntax.
static const transfer_syntax explicit_vr_big_endian
Explicit VR Big Endian (1.2.840.10008.1.2.2) - Retired.
static const transfer_syntax jpeg2000_lossy
JPEG 2000 Image Compression (1.2.840.10008.1.2.4.91)
transfer_syntax(std::string_view uid)
Constructs a transfer_syntax from a UID string.
static const transfer_syntax jpegxl_jpeg_recompression
JPEG XL JPEG Recompression (1.2.840.10008.1.2.4.111) - Supplement 232.
std::string_view uid() const noexcept
Returns the Transfer Syntax UID.
static const transfer_syntax htj2k_lossy
HTJ2K (1.2.840.10008.1.2.4.203) - Lossless or Lossy.
byte_order endianness() const noexcept
Returns the byte ordering for this Transfer Syntax.
static const transfer_syntax hevc_main
HEVC/H.265 Main Profile / Level 5.1 (1.2.840.10008.1.2.4.107)
static const transfer_syntax hevc_main10
HEVC/H.265 Main 10 Profile / Level 5.1 (1.2.840.10008.1.2.4.108)
static const transfer_syntax jpegxl_lossless
JPEG XL Lossless (1.2.840.10008.1.2.4.110) - Supplement 232.
static const transfer_syntax frame_deflate
Frame Deflate (1.2.840.10008.1.2.11) - Supplement 244.
bool operator!=(const transfer_syntax &other) const noexcept
Compares two Transfer Syntaxes by UID.
static const transfer_syntax jpeg_baseline
JPEG Baseline (Process 1) (1.2.840.10008.1.2.4.50)
std::string_view name() const noexcept
Returns the human-readable name of the Transfer Syntax.
bool operator==(const transfer_syntax &other) const noexcept
Compares two Transfer Syntaxes by UID.
static const transfer_syntax htj2k_lossless
HTJ2K Lossless Only (1.2.840.10008.1.2.4.201)
static const transfer_syntax rle_lossless
RLE Lossless (1.2.840.10008.1.2.5)
bool is_supported() const noexcept
Checks if this Transfer Syntax is currently supported.
static const transfer_syntax explicit_vr_little_endian
Explicit VR Little Endian (1.2.840.10008.1.2.1)
static const transfer_syntax implicit_vr_little_endian
Implicit VR Little Endian (1.2.840.10008.1.2)
static const transfer_syntax jpeg_lossless
JPEG Lossless, Non-Hierarchical (1.2.840.10008.1.2.4.70)
bool is_deflated() const noexcept
Checks if this Transfer Syntax uses deflate compression.
static const transfer_syntax jpegxl_lossy
JPEG XL (1.2.840.10008.1.2.4.112) - Supplement 232.
static const transfer_syntax deflated_explicit_vr_le
Deflated Explicit VR Little Endian (1.2.840.10008.1.2.1.99)
static const transfer_syntax htj2k_rpcl
HTJ2K RPCL (1.2.840.10008.1.2.4.202) - Lossless Only.
bool is_valid() const noexcept
Checks if this is a recognized DICOM Transfer Syntax.
static const transfer_syntax jpeg2000_lossless
JPEG 2000 Image Compression (Lossless Only) (1.2.840.10008.1.2.4.90)
bool is_encapsulated() const noexcept
Checks if this Transfer Syntax uses encapsulated (compressed) format.
std::optional< transfer_syntax > find_transfer_syntax(std::string_view uid)
Looks up a Transfer Syntax by its UID.
std::vector< transfer_syntax > all_transfer_syntaxes()
Returns a list of all known Transfer Syntaxes.
std::vector< transfer_syntax > supported_transfer_syntaxes()
Returns a list of all supported Transfer Syntaxes.
byte_order
Byte ordering for DICOM data encoding.
Definition byte_order.h:22
@ little_endian
Least significant byte first (most common)
@ big_endian
Most significant byte first (legacy, rarely used)
vr_encoding
Value Representation encoding mode.
Definition byte_order.h:33
@ explicit_vr
VR explicitly encoded in the data stream.
@ implicit
VR determined from data dictionary lookup.
vr_encoding vr
std::string_view uid
byte_order endian
bool deflated
bool supported
std::string_view name
bool encapsulated