PACS System 0.1.0
PACS DICOM system library
Loading...
Searching...
No Matches
kcenon::pacs::encoding Namespace Reference

Namespaces

namespace  compression
 
namespace  simd
 

Classes

struct  character_set_info
 Information about a DICOM character set. More...
 
class  explicit_vr_big_endian_codec
 Encoder/decoder for Explicit VR Big Endian transfer syntax. More...
 
class  explicit_vr_codec
 Encoder/decoder for Explicit VR Little Endian transfer syntax. More...
 
class  implicit_vr_codec
 Encoder/decoder for Implicit VR Little Endian transfer syntax. More...
 
struct  specific_character_set
 Parsed representation of a multi-valued Specific Character Set. More...
 
struct  text_segment
 A text segment with its associated character set. More...
 
class  transfer_syntax
 Represents a DICOM Transfer Syntax. More...
 
struct  vr_info
 Metadata structure containing comprehensive VR properties. More...
 

Enumerations

enum class  byte_order { little_endian , big_endian }
 Byte ordering for DICOM data encoding. More...
 
enum class  vr_encoding { implicit , explicit_vr }
 Value Representation encoding mode. More...
 
enum class  vr_type : uint16_t {
  AE = 0x4145 , AS = 0x4153 , CS = 0x4353 , DA = 0x4441 ,
  DS = 0x4453 , DT = 0x4454 , IS = 0x4953 , LO = 0x4C4F ,
  LT = 0x4C54 , PN = 0x504E , SH = 0x5348 , ST = 0x5354 ,
  TM = 0x544D , UC = 0x5543 , UI = 0x5549 , UR = 0x5552 ,
  UT = 0x5554 , FL = 0x464C , FD = 0x4644 , SL = 0x534C ,
  SS = 0x5353 , UL = 0x554C , US = 0x5553 , OB = 0x4F42 ,
  OD = 0x4F44 , OF = 0x4F46 , OL = 0x4F4C , OV = 0x4F56 ,
  OW = 0x4F57 , UN = 0x554E , AT = 0x4154 , SQ = 0x5351 ,
  SV = 0x5356 , UV = 0x5556
}
 DICOM Value Representation (VR) types. More...
 

Functions

std::string get_decoded_string (const core::dicom_dataset &ds, core::dicom_tag tag, std::string_view default_value="")
 Get a string value from dataset, decoded to UTF-8.
 
void set_encoded_string (core::dicom_dataset &ds, core::dicom_tag tag, vr_type vr, std::string_view utf8_value)
 Set a string value in dataset, encoding from UTF-8.
 
Single Value Byte Swapping
constexpr uint16_t byte_swap16 (uint16_t value) noexcept
 Swaps bytes in a 16-bit value.
 
constexpr uint32_t byte_swap32 (uint32_t value) noexcept
 Swaps bytes in a 32-bit value.
 
constexpr uint64_t byte_swap64 (uint64_t value) noexcept
 Swaps bytes in a 64-bit value.
 
Big Endian Read/Write Functions
constexpr uint16_t read_be16 (const uint8_t *data) noexcept
 Reads a 16-bit value from big-endian bytes.
 
constexpr uint32_t read_be32 (const uint8_t *data) noexcept
 Reads a 32-bit value from big-endian bytes.
 
constexpr uint64_t read_be64 (const uint8_t *data) noexcept
 Reads a 64-bit value from big-endian bytes.
 
void write_be16 (std::vector< uint8_t > &buffer, uint16_t value)
 Writes a 16-bit value in big-endian byte order.
 
void write_be32 (std::vector< uint8_t > &buffer, uint32_t value)
 Writes a 32-bit value in big-endian byte order.
 
void write_be64 (std::vector< uint8_t > &buffer, uint64_t value)
 Writes a 64-bit value in big-endian byte order.
 
Bulk Byte Swapping for VR Types
std::vector< uint8_t > swap_ow_bytes (std::span< const uint8_t > data)
 Swaps bytes in-place for OW (Other Word) data.
 
std::vector< uint8_t > swap_ol_bytes (std::span< const uint8_t > data)
 Swaps bytes in-place for OL (Other Long) data.
 
std::vector< uint8_t > swap_of_bytes (std::span< const uint8_t > data)
 Swaps bytes in-place for OF (Other Float) data.
 
std::vector< uint8_t > swap_od_bytes (std::span< const uint8_t > data)
 Swaps bytes in-place for OD (Other Double) data.
 
std::vector< uint8_t > swap_at_bytes (std::span< const uint8_t > data)
 Swaps bytes for AT (Attribute Tag) data.
 
Numeric Value Byte Swapping
std::vector< uint8_t > swap_us_bytes (std::span< const uint8_t > data)
 Swaps bytes for US (Unsigned Short) value in raw data.
 
std::vector< uint8_t > swap_ss_bytes (std::span< const uint8_t > data)
 Swaps bytes for SS (Signed Short) value in raw data.
 
std::vector< uint8_t > swap_ul_bytes (std::span< const uint8_t > data)
 Swaps bytes for UL (Unsigned Long) value in raw data.
 
std::vector< uint8_t > swap_sl_bytes (std::span< const uint8_t > data)
 Swaps bytes for SL (Signed Long) value in raw data.
 
std::vector< uint8_t > swap_fl_bytes (std::span< const uint8_t > data)
 Swaps bytes for FL (Float) value in raw data.
 
std::vector< uint8_t > swap_fd_bytes (std::span< const uint8_t > data)
 Swaps bytes for FD (Double) value in raw data.
 
Character Set Registry
const character_set_infofind_character_set (std::string_view defined_term) noexcept
 Look up character set info by DICOM Defined Term.
 
const character_set_infofind_character_set_by_ir (int iso_ir_number) noexcept
 Look up character set info by ISO-IR number.
 
const character_set_infodefault_character_set () noexcept
 Get the default character set (ISO-IR 6, ASCII).
 
std::vector< const character_set_info * > all_character_sets () noexcept
 Get all registered character sets.
 
Specific Character Set Parsing
specific_character_set parse_specific_character_set (std::string_view value)
 Parse a Specific Character Set (0008,0005) value.
 
ISO 2022 Escape Sequence Detection
std::vector< text_segmentsplit_by_escape_sequences (std::string_view text, const specific_character_set &scs)
 Split a string into segments by ISO 2022 escape sequences.
 
String Decoding
std::string decode_to_utf8 (std::string_view text, const specific_character_set &scs)
 Decode a DICOM string to UTF-8 using the given character set.
 
std::string convert_to_utf8 (std::string_view text, const character_set_info &charset)
 Decode a single segment from a specific encoding to UTF-8.
 
std::string decode_person_name (std::string_view pn_value, const specific_character_set &scs)
 Decode a Person Name (PN) value to UTF-8.
 
std::string encode_from_utf8 (std::string_view utf8_text, const specific_character_set &scs)
 Encode a UTF-8 string to the target character set encoding.
 
std::string convert_from_utf8 (std::string_view utf8_text, const character_set_info &charset)
 Encode a single UTF-8 segment to a specific character set.
 
Registry Functions
std::optional< transfer_syntaxfind_transfer_syntax (std::string_view uid)
 Looks up a Transfer Syntax by its UID.
 
std::vector< transfer_syntaxsupported_transfer_syntaxes ()
 Returns a list of all supported Transfer Syntaxes.
 
std::vector< transfer_syntaxall_transfer_syntaxes ()
 Returns a list of all known Transfer Syntaxes.
 
VR Information Lookup
const vr_infoget_vr_info (vr_type vr)
 Retrieves comprehensive metadata for a VR type.
 
Value Validation Functions
bool validate_value (vr_type vr, std::span< const uint8_t > data)
 Validates binary data against VR encoding rules.
 
bool validate_string (vr_type vr, std::string_view value)
 Validates a string value against VR encoding rules.
 
Padding Utilities
std::vector< uint8_t > pad_to_even (vr_type vr, std::span< const uint8_t > data)
 Pads data to even length as required by DICOM.
 
std::string trim_padding (vr_type vr, std::string_view value)
 Removes trailing padding characters from a string value.
 
Character Set Validation
bool is_valid_charset (vr_type vr, std::string_view value)
 Validates that a string uses only allowed characters for its VR.
 
String Conversion Functions
constexpr std::string_view to_string (vr_type vr) noexcept
 Converts a vr_type to its two-character string representation.
 
constexpr std::optional< vr_typefrom_string (std::string_view str) noexcept
 Parses a two-character string to a vr_type.
 
VR Category Classification Functions
constexpr bool is_string_vr (vr_type vr) noexcept
 Checks if a VR is a string type.
 
constexpr bool is_binary_vr (vr_type vr) noexcept
 Checks if a VR is a binary/raw byte type.
 
constexpr bool is_numeric_vr (vr_type vr) noexcept
 Checks if a VR is a numeric type.
 
constexpr bool has_explicit_32bit_length (vr_type vr) noexcept
 Checks if a VR requires 32-bit length field in Explicit VR encoding.
 
Additional VR Utility Functions
constexpr std::size_t fixed_length (vr_type vr) noexcept
 Gets the fixed size of a VR if applicable.
 
constexpr bool is_fixed_length (vr_type vr) noexcept
 Checks if a VR has a fixed length.
 
constexpr char padding_char (vr_type vr) noexcept
 Gets the padding character for a VR.
 

Enumeration Type Documentation

◆ byte_order

Byte ordering for DICOM data encoding.

DICOM supports both little-endian and big-endian byte ordering. Little-endian is the most common and is used by default in DICOM.

Enumerator
little_endian 

Least significant byte first (most common)

big_endian 

Most significant byte first (legacy, rarely used)

Definition at line 22 of file byte_order.h.

22 {
25};
@ little_endian
Least significant byte first (most common)
@ big_endian
Most significant byte first (legacy, rarely used)

◆ vr_encoding

Value Representation encoding mode.

Determines whether VR (Value Representation) is explicitly encoded in the data stream or implicitly determined from the tag.

Enumerator
implicit 

VR determined from data dictionary lookup.

explicit_vr 

VR explicitly encoded in the data stream.

Definition at line 33 of file byte_order.h.

33 {
34 implicit,
36};
@ explicit_vr
VR explicitly encoded in the data stream.
@ implicit
VR determined from data dictionary lookup.

◆ vr_type

enum class kcenon::pacs::encoding::vr_type : uint16_t
strong

DICOM Value Representation (VR) types.

Value Representation specifies the data type and format of the data element value. Each VR is encoded as two ASCII characters (e.g., "PN" for Person Name). The enum values are the uint16_t representation of these two ASCII characters.

See also
DICOM PS3.5 Section 6.2 - Value Representation (VR)
Enumerator
AE 

Application Entity (16 chars max)

AS 

Age String (4 chars, format: nnnD/W/M/Y)

CS 

Code String (16 chars max, uppercase + digits + space + underscore)

DA 

Date (8 chars, format: YYYYMMDD)

DS 

Decimal String (16 chars max)

DT 

Date Time (26 chars max)

IS 

Integer String (12 chars max)

LO 

Long String (64 chars max)

LT 

Long Text (10240 chars max)

PN 

Person Name (64 chars max per component group)

SH 

Short String (16 chars max)

ST 

Short Text (1024 chars max)

TM 

Time (14 chars max, format: HHMMSS.FFFFFF)

UC 

Unlimited Characters (2^32-2 max)

UI 

Unique Identifier (64 chars max)

UR 

Universal Resource Identifier (2^32-2 max)

UT 

Unlimited Text (2^32-2 max)

FL 

Floating Point Single (4 bytes)

FD 

Floating Point Double (8 bytes)

SL 

Signed Long (4 bytes)

SS 

Signed Short (2 bytes)

UL 

Unsigned Long (4 bytes)

US 

Unsigned Short (2 bytes)

OB 

Other Byte (variable length)

OD 

Other Double (variable length)

OF 

Other Float (variable length)

OL 

Other Long (variable length)

OV 

Other 64-bit Very Long (variable length)

OW 

Other Word (variable length)

UN 

Unknown (variable length)

AT 

Attribute Tag (4 bytes)

SQ 

Sequence of Items (undefined length)

SV 

Signed 64-bit Very Long (8 bytes)

UV 

Unsigned 64-bit Very Long (8 bytes)

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_dataset.h, /home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/dicom_element.h, /home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/pool_manager.h, /home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/core/private_tag_registry.h, and /home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/container_adapter.h.

Definition at line 29 of file vr_type.h.

29 : uint16_t {
30 // String VRs
31 AE = 0x4145,
32 AS = 0x4153,
33 CS = 0x4353,
34 DA = 0x4441,
35 DS = 0x4453,
36 DT = 0x4454,
37 IS = 0x4953,
38 LO = 0x4C4F,
39 LT = 0x4C54,
40 PN = 0x504E,
41 SH = 0x5348,
42 ST = 0x5354,
43 TM = 0x544D,
44 UC = 0x5543,
45 UI = 0x5549,
46 UR = 0x5552,
47 UT = 0x5554,
48
49 // Numeric VRs (binary encoded)
50 FL = 0x464C,
51 FD = 0x4644,
52 SL = 0x534C,
53 SS = 0x5353,
54 UL = 0x554C,
55 US = 0x5553,
56
57 // Binary VRs (raw bytes)
58 OB = 0x4F42,
59 OD = 0x4F44,
60 OF = 0x4F46,
61 OL = 0x4F4C,
62 OV = 0x4F56,
63 OW = 0x4F57,
64 UN = 0x554E,
65
66 // Special VRs
67 AT = 0x4154,
68 SQ = 0x5351,
69 SV = 0x5356,
70 UV = 0x5556,
71};
@ OB
Other Byte (variable length)
@ DA
Date (8 chars, format: YYYYMMDD)
@ UN
Unknown (variable length)
@ IS
Integer String (12 chars max)
@ SQ
Sequence of Items (undefined length)
@ UR
Universal Resource Identifier (2^32-2 max)
@ OV
Other 64-bit Very Long (variable length)
@ LO
Long String (64 chars max)
@ DS
Decimal String (16 chars max)
@ DT
Date Time (26 chars max)
@ UL
Unsigned Long (4 bytes)
@ UC
Unlimited Characters (2^32-2 max)
@ UI
Unique Identifier (64 chars max)
@ SL
Signed Long (4 bytes)
@ US
Unsigned Short (2 bytes)
@ OD
Other Double (variable length)
@ PN
Person Name (64 chars max per component group)
@ OF
Other Float (variable length)
@ UT
Unlimited Text (2^32-2 max)
@ CS
Code String (16 chars max, uppercase + digits + space + underscore)
@ OW
Other Word (variable length)
@ AS
Age String (4 chars, format: nnnD/W/M/Y)
@ FD
Floating Point Double (8 bytes)
@ FL
Floating Point Single (4 bytes)
@ TM
Time (14 chars max, format: HHMMSS.FFFFFF)
@ OL
Other Long (variable length)
@ LT
Long Text (10240 chars max)
@ SV
Signed 64-bit Very Long (8 bytes)
@ SS
Signed Short (2 bytes)
@ UV
Unsigned 64-bit Very Long (8 bytes)
@ AE
Application Entity (16 chars max)
@ SH
Short String (16 chars max)
@ ST
Short Text (1024 chars max)
@ AT
Attribute Tag (4 bytes)

Function Documentation

◆ all_character_sets()

std::vector< const character_set_info * > kcenon::pacs::encoding::all_character_sets ( )
nodiscardnoexcept

Get all registered character sets.

Returns
Vector of pointers to all registered character_set_info entries

Definition at line 436 of file character_set.cpp.

436 {
437 std::vector<const character_set_info*> result;
438 result.reserve(charset_registry.size() + 2);
439 for (const auto& entry : charset_registry) {
440 result.push_back(&entry);
441 }
442 result.push_back(&charset_ir_58);
443 result.push_back(&charset_gb18030);
444 return result;
445}

◆ all_transfer_syntaxes()

std::vector< transfer_syntax > kcenon::pacs::encoding::all_transfer_syntaxes ( )
nodiscard

Returns a list of all known Transfer Syntaxes.

Returns
Vector of all registered transfer_syntax instances

Definition at line 394 of file transfer_syntax.cpp.

394 {
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}
Represents a DICOM Transfer Syntax.

◆ byte_swap16()

uint16_t kcenon::pacs::encoding::byte_swap16 ( uint16_t value)
nodiscardconstexprnoexcept

Swaps bytes in a 16-bit value.

Parameters
valueThe value to swap
Returns
The byte-swapped value

Example: 0x1234 -> 0x3412

Definition at line 40 of file byte_swap.h.

40 {
41 return static_cast<uint16_t>((value >> 8) | (value << 8));
42}

◆ byte_swap32()

uint32_t kcenon::pacs::encoding::byte_swap32 ( uint32_t value)
nodiscardconstexprnoexcept

Swaps bytes in a 32-bit value.

Parameters
valueThe value to swap
Returns
The byte-swapped value

Example: 0x12345678 -> 0x78563412

Definition at line 51 of file byte_swap.h.

51 {
52 return ((value >> 24) & 0x000000FF) |
53 ((value >> 8) & 0x0000FF00) |
54 ((value << 8) & 0x00FF0000) |
55 ((value << 24) & 0xFF000000);
56}

◆ byte_swap64()

uint64_t kcenon::pacs::encoding::byte_swap64 ( uint64_t value)
nodiscardconstexprnoexcept

Swaps bytes in a 64-bit value.

Parameters
valueThe value to swap
Returns
The byte-swapped value

Example: 0x123456789ABCDEF0 -> 0xF0DEBC9A78563412

Definition at line 65 of file byte_swap.h.

65 {
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}

◆ convert_from_utf8()

std::string kcenon::pacs::encoding::convert_from_utf8 ( std::string_view utf8_text,
const character_set_info & charset )
nodiscard

Encode a single UTF-8 segment to a specific character set.

Parameters
utf8_textThe UTF-8 encoded source string
charsetThe target character set
Returns
Encoded string in the target encoding

Definition at line 684 of file character_set.cpp.

686 {
687
688 if (utf8_text.empty()) {
689 return {};
690 }
691
692 if (charset.encoding_name == "ASCII" ||
693 charset.encoding_name == "UTF-8") {
694 return std::string(utf8_text);
695 }
696
697 return icu_convert_from_utf8(utf8_text, charset);
698}
std::string_view encoding_name
ICU converter name (e.g., "EUC-KR")

References kcenon::pacs::encoding::character_set_info::encoding_name.

Referenced by encode_from_utf8().

Here is the caller graph for this function:

◆ convert_to_utf8()

std::string kcenon::pacs::encoding::convert_to_utf8 ( std::string_view text,
const character_set_info & charset )
nodiscard

Decode a single segment from a specific encoding to UTF-8.

Parameters
textThe raw bytes in the source encoding
charsetThe character set of the source bytes
Returns
UTF-8 encoded string

Uses ICU (ucnv_convert) for encoding conversion. Falls back to raw bytes if conversion fails.

Definition at line 589 of file character_set.cpp.

591 {
592
593 if (text.empty()) {
594 return {};
595 }
596
597 // ASCII and UTF-8 need no conversion
598 if (charset.encoding_name == "ASCII" ||
599 charset.encoding_name == "UTF-8") {
600 return std::string(text);
601 }
602
603 return icu_convert_to_utf8(text, charset);
604}

References kcenon::pacs::encoding::character_set_info::encoding_name.

Referenced by decode_to_utf8().

Here is the caller graph for this function:

◆ decode_person_name()

std::string kcenon::pacs::encoding::decode_person_name ( std::string_view pn_value,
const specific_character_set & scs )
nodiscard

Decode a Person Name (PN) value to UTF-8.

Parameters
pn_valueThe raw PN value (may contain '=' component group separators)
scsThe Specific Character Set configuration
Returns
UTF-8 encoded Person Name string

PN values have up to three component groups separated by '=':

  • Alphabetic (single-byte)
  • Ideographic (multi-byte, e.g., kanji/hangul)
  • Phonetic (single-byte, e.g., romaji/jamo)

Each component group is decoded independently.

Definition at line 641 of file character_set.cpp.

643 {
644
645 if (pn_value.empty()) {
646 return {};
647 }
648
649 // Split by '=' into component groups
650 // (Alphabetic=Ideographic=Phonetic)
651 std::string result;
652 result.reserve(pn_value.size() * 2);
653
654 size_t start = 0;
655 bool first = true;
656
657 while (start <= pn_value.size()) {
658 size_t eq_pos = pn_value.find('=', start);
659 std::string_view group;
660 if (eq_pos == std::string_view::npos) {
661 group = pn_value.substr(start);
662 start = pn_value.size() + 1;
663 } else {
664 group = pn_value.substr(start, eq_pos - start);
665 start = eq_pos + 1;
666 }
667
668 if (!first) {
669 result += '=';
670 }
671 first = false;
672
673 // Decode each component group independently
674 result += decode_to_utf8(group, scs);
675 }
676
677 return result;
678}
std::string decode_to_utf8(std::string_view text, const specific_character_set &scs)
Decode a DICOM string to UTF-8 using the given character set.

References decode_to_utf8().

Here is the call graph for this function:

◆ decode_to_utf8()

std::string kcenon::pacs::encoding::decode_to_utf8 ( std::string_view text,
const specific_character_set & scs )
nodiscard

Decode a DICOM string to UTF-8 using the given character set.

Parameters
textThe raw DICOM string bytes
scsThe Specific Character Set configuration
Returns
UTF-8 encoded string

This is the main entry point for character set conversion. It:

  1. Checks if conversion is needed (UTF-8 passthrough)
  2. Splits text by escape sequences (if ISO 2022)
  3. Converts each segment to UTF-8
  4. Concatenates the results

If conversion fails for any segment, the raw bytes are passed through.

Definition at line 606 of file character_set.cpp.

608 {
609
610 if (text.empty()) {
611 return {};
612 }
613
614 // Fast path: UTF-8 passthrough
615 if (scs.is_utf8()) {
616 return std::string(text);
617 }
618
619 // Fast path: single-byte charset without extensions
620 if (!scs.uses_extensions()) {
621 return convert_to_utf8(text, *scs.default_set);
622 }
623
624 // ISO 2022: split by escape sequences and convert each segment
625 auto segments = split_by_escape_sequences(text, scs);
626
627 std::string result;
628 result.reserve(text.size() * 2);
629
630 for (const auto& seg : segments) {
631 if (seg.charset) {
632 result += convert_to_utf8(seg.text, *seg.charset);
633 } else {
634 result.append(seg.text);
635 }
636 }
637
638 return result;
639}
std::vector< text_segment > split_by_escape_sequences(std::string_view text, const specific_character_set &scs)
Split a string into segments by ISO 2022 escape sequences.
std::string convert_to_utf8(std::string_view text, const character_set_info &charset)
Decode a single segment from a specific encoding to UTF-8.
bool uses_extensions() const noexcept
Whether this uses ISO 2022 code extensions.
bool is_utf8() const noexcept
Check if UTF-8 is the active character set.
const character_set_info * default_set
Character set for default (G0) repertoire.

References convert_to_utf8(), kcenon::pacs::encoding::specific_character_set::default_set, kcenon::pacs::encoding::specific_character_set::is_utf8(), split_by_escape_sequences(), and kcenon::pacs::encoding::specific_character_set::uses_extensions().

Referenced by decode_person_name(), and get_decoded_string().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ default_character_set()

const character_set_info & kcenon::pacs::encoding::default_character_set ( )
nodiscardnoexcept

Get the default character set (ISO-IR 6, ASCII).

Returns
Reference to the ASCII character set info

Definition at line 431 of file character_set.cpp.

431 {
432 // ISO_IR 6 (ASCII) is always the first entry
433 return charset_registry[0];
434}

Referenced by parse_specific_character_set().

Here is the caller graph for this function:

◆ encode_from_utf8()

std::string kcenon::pacs::encoding::encode_from_utf8 ( std::string_view utf8_text,
const specific_character_set & scs )
nodiscard

Encode a UTF-8 string to the target character set encoding.

Parameters
utf8_textThe UTF-8 encoded source string
scsThe Specific Character Set configuration
Returns
Encoded string with ISO 2022 escape sequences if needed

This is the reverse of decode_to_utf8(). It converts a UTF-8 string to the encoding specified by the Specific Character Set, inserting ISO 2022 escape sequences as appropriate for CJK text.

If the charset is UTF-8, the input is returned unchanged. If conversion fails, the raw UTF-8 bytes are returned as-is.

Definition at line 700 of file character_set.cpp.

702 {
703
704 if (utf8_text.empty()) {
705 return {};
706 }
707
708 // Fast path: UTF-8 passthrough
709 if (scs.is_utf8()) {
710 return std::string(utf8_text);
711 }
712
713 // No extensions: simple single-charset conversion
714 if (!scs.uses_extensions()) {
715 return convert_from_utf8(utf8_text, *scs.default_set);
716 }
717
718 // ISO 2022 with extensions: detect non-ASCII runs and wrap with
719 // escape sequences for the first available CJK extension charset.
720 // Strategy: scan UTF-8 text byte by byte. ASCII bytes (< 0x80) use
721 // the default charset. Non-ASCII byte runs are converted using the
722 // first multi-byte extension charset, bracketed by escape sequences.
723
724 const character_set_info* mb_charset = nullptr;
725 for (const auto* cs : scs.extension_sets) {
726 if (cs && cs->is_multi_byte) {
727 mb_charset = cs;
728 break;
729 }
730 }
731
732 if (!mb_charset) {
733 // No multi-byte extension available; convert with default
734 return convert_from_utf8(utf8_text, *scs.default_set);
735 }
736
737 std::string result;
738 result.reserve(utf8_text.size() * 2);
739
740 bool in_multibyte = false;
741 size_t run_start = 0;
742
743 for (size_t i = 0; i < utf8_text.size(); ) {
744 auto uc = static_cast<unsigned char>(utf8_text[i]);
745 bool is_ascii = (uc < 0x80);
746
747 if (is_ascii) {
748 if (in_multibyte) {
749 // Flush multi-byte run
750 auto mb_run = utf8_text.substr(run_start, i - run_start);
751 result.append(mb_charset->escape_sequence);
752 result += convert_from_utf8(mb_run, *mb_charset);
753 // Return to ASCII
754 result.append(esc_ir_6);
755 in_multibyte = false;
756 }
757 if (!in_multibyte && i == run_start) {
758 // Continue ASCII
759 }
760 run_start = i;
761 result += utf8_text[i];
762 ++i;
763 run_start = i;
764 } else {
765 if (!in_multibyte) {
766 in_multibyte = true;
767 run_start = i;
768 }
769 // Skip multi-byte UTF-8 sequence
770 if (uc < 0xC0) { ++i; }
771 else if (uc < 0xE0) { i += 2; }
772 else if (uc < 0xF0) { i += 3; }
773 else { i += 4; }
774 // Clamp to text size
775 if (i > utf8_text.size()) { i = utf8_text.size(); }
776 }
777 }
778
779 // Flush remaining multi-byte run
780 if (in_multibyte && run_start < utf8_text.size()) {
781 auto mb_run = utf8_text.substr(run_start);
782 result.append(mb_charset->escape_sequence);
783 result += convert_from_utf8(mb_run, *mb_charset);
784 result.append(esc_ir_6);
785 }
786
787 return result;
788}
std::string convert_from_utf8(std::string_view utf8_text, const character_set_info &charset)
Encode a single UTF-8 segment to a specific character set.
std::vector< const character_set_info * > extension_sets
Additional character sets activated by escape sequences.

References convert_from_utf8(), kcenon::pacs::encoding::specific_character_set::default_set, kcenon::pacs::encoding::character_set_info::escape_sequence, kcenon::pacs::encoding::specific_character_set::extension_sets, kcenon::pacs::encoding::specific_character_set::is_utf8(), and kcenon::pacs::encoding::specific_character_set::uses_extensions().

Referenced by set_encoded_string().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ find_character_set()

const character_set_info * kcenon::pacs::encoding::find_character_set ( std::string_view defined_term)
nodiscardnoexcept

Look up character set info by DICOM Defined Term.

Parameters
defined_termThe DICOM Defined Term (e.g., "ISO 2022 IR 149", "ISO_IR 100")
Returns
Pointer to character_set_info, or nullptr if not found

Supports both forms: "ISO_IR 100" (without code extensions) and "ISO 2022 IR 149" (with code extensions).

Definition at line 421 of file character_set.cpp.

422 {
423 return find_in_registry(defined_term);
424}

◆ find_character_set_by_ir()

const character_set_info * kcenon::pacs::encoding::find_character_set_by_ir ( int iso_ir_number)
nodiscardnoexcept

Look up character set info by ISO-IR number.

Parameters
iso_ir_numberThe ISO-IR number (e.g., 149, 87, 100)
Returns
Pointer to character_set_info, or nullptr if not found

Definition at line 426 of file character_set.cpp.

427 {
428 return find_by_ir_number(iso_ir_number);
429}

◆ find_transfer_syntax()

std::optional< transfer_syntax > kcenon::pacs::encoding::find_transfer_syntax ( std::string_view uid)
nodiscard

Looks up a Transfer Syntax by its UID.

Allow registry functions to use private constructor.

Parameters
uidThe Transfer Syntax UID to search for
Returns
The transfer_syntax if found, std::nullopt otherwise

Definition at line 371 of file transfer_syntax.cpp.

371 {
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}
std::string_view uid

◆ fixed_length()

std::size_t kcenon::pacs::encoding::fixed_length ( vr_type vr)
nodiscardconstexprnoexcept

Gets the fixed size of a VR if applicable.

Parameters
vrThe VR type to check
Returns
The fixed size in bytes, or 0 if the VR has variable length

Fixed-length VRs have a predetermined size regardless of value.

Definition at line 260 of file vr_type.h.

260 {
261 switch (vr) {
262 case vr_type::AT: return 4; // Attribute Tag
263 case vr_type::FL: return 4; // Float
264 case vr_type::FD: return 8; // Double
265 case vr_type::SL: return 4; // Signed Long
266 case vr_type::SS: return 2; // Signed Short
267 case vr_type::SV: return 8; // Signed 64-bit
268 case vr_type::UL: return 4; // Unsigned Long
269 case vr_type::US: return 2; // Unsigned Short
270 case vr_type::UV: return 8; // Unsigned 64-bit
271 default: return 0; // Variable length
272 }
273}
vr_encoding vr

References AT, FD, FL, SL, SS, SV, UL, US, UV, and vr.

Referenced by kcenon::pacs::core::dicom_file::decode_explicit_vr_be(), kcenon::pacs::core::dicom_file::encode_explicit_vr_be(), and is_fixed_length().

Here is the caller graph for this function:

◆ from_string()

std::optional< vr_type > kcenon::pacs::encoding::from_string ( std::string_view str)
nodiscardconstexprnoexcept

Parses a two-character string to a vr_type.

Parameters
strThe string to parse (must be exactly 2 characters)
Returns
The corresponding vr_type, or std::nullopt if not recognized

Definition at line 132 of file vr_type.h.

132 {
133 if (str.size() != 2) {
134 return std::nullopt;
135 }
136
137 // Convert two ASCII chars to uint16_t (big-endian: first char is high byte)
138 const auto code = static_cast<uint16_t>(
139 (static_cast<uint16_t>(static_cast<unsigned char>(str[0])) << 8) |
140 static_cast<uint16_t>(static_cast<unsigned char>(str[1]))
141 );
142
143 // Validate by checking if the code corresponds to a known VR
144 switch (static_cast<vr_type>(code)) {
145 case vr_type::AE: case vr_type::AS: case vr_type::AT:
146 case vr_type::CS: case vr_type::DA: case vr_type::DS:
147 case vr_type::DT: case vr_type::FD: case vr_type::FL:
148 case vr_type::IS: case vr_type::LO: case vr_type::LT:
149 case vr_type::OB: case vr_type::OD: case vr_type::OF:
150 case vr_type::OL: case vr_type::OV: case vr_type::OW:
151 case vr_type::PN: case vr_type::SH: case vr_type::SL:
152 case vr_type::SQ: case vr_type::SS: case vr_type::ST:
153 case vr_type::SV: case vr_type::TM: case vr_type::UC:
154 case vr_type::UI: case vr_type::UL: case vr_type::UN:
155 case vr_type::UR: case vr_type::US: case vr_type::UT:
156 case vr_type::UV:
157 return static_cast<vr_type>(code);
158 default:
159 return std::nullopt;
160 }
161}
std::string_view code

References AE, AS, AT, code, CS, DA, DS, DT, FD, FL, IS, LO, LT, OB, OD, OF, OL, OV, OW, PN, SH, SL, SQ, SS, ST, SV, TM, UC, UI, UL, UN, UR, US, UT, and UV.

Referenced by kcenon::pacs::encoding::explicit_vr_big_endian_codec::decode_element(), kcenon::pacs::encoding::explicit_vr_codec::decode_element(), kcenon::pacs::core::dicom_file::decode_explicit_vr_be(), kcenon::pacs::core::dicom_file::decode_explicit_vr_le(), kcenon::pacs::core::dicom_file::decode_implicit_vr_le(), kcenon::pacs::integration::container_adapter::parse_element_key(), and kcenon::pacs::core::dicom_file::parse_meta_information().

Here is the caller graph for this function:

◆ get_decoded_string()

std::string kcenon::pacs::encoding::get_decoded_string ( const core::dicom_dataset & ds,
core::dicom_tag tag,
std::string_view default_value = "" )
nodiscard

Get a string value from dataset, decoded to UTF-8.

Parameters
dsThe DICOM dataset to read from
tagThe DICOM tag to look up
default_valueValue to return if element not found
Returns
UTF-8 decoded string value, or default_value if not found

Looks up Specific Character Set (0008,0005) in the dataset and uses it to decode the raw string bytes to UTF-8. If no Specific Character Set is present, ASCII decoding is assumed (raw passthrough).

Definition at line 16 of file dataset_charset.cpp.

19 {
20
21 const auto* elem = ds.get(tag);
22 if (elem == nullptr) {
23 return std::string{default_value};
24 }
25
26 auto raw = elem->as_string();
27 if (!raw.is_ok()) {
28 return std::string{default_value};
29 }
30
31 // Look up Specific Character Set (0008,0005)
32 auto scs_value = ds.get_string(core::tags::specific_character_set);
33 auto scs = parse_specific_character_set(scs_value);
34
35 return decode_to_utf8(raw.value(), scs);
36}
auto get(dicom_tag tag) noexcept -> dicom_element *
Get a pointer to the element with the given tag.
auto get_string(dicom_tag tag, std::string_view default_value="") const -> std::string
Get the string value of an element.
specific_character_set parse_specific_character_set(std::string_view value)
Parse a Specific Character Set (0008,0005) value.

References decode_to_utf8(), kcenon::pacs::core::dicom_dataset::get(), kcenon::pacs::core::dicom_dataset::get_string(), parse_specific_character_set(), and kcenon::pacs::core::tags::specific_character_set.

Here is the call graph for this function:

◆ get_vr_info()

const vr_info & kcenon::pacs::encoding::get_vr_info ( vr_type vr)
nodiscard

Retrieves comprehensive metadata for a VR type.

Parameters
vrThe VR type to look up
Returns
Reference to vr_info structure containing VR properties

This function provides all properties needed for encoding/decoding operations, including name, maximum length, padding requirements, and fixed/variable length information.

Note
Returns info for vr_type::UN if an unknown VR is provided.

Definition at line 131 of file vr_info.cpp.

131 {
132 const auto& map = get_vr_map();
133 auto it = map.find(vr);
134 if (it != map.end()) {
135 return *it->second;
136 }
137 // Return UN info for unknown VR types
138 return un_info;
139}

References vr.

Referenced by pad_to_even(), trim_padding(), validate_string(), and validate_value().

Here is the caller graph for this function:

◆ has_explicit_32bit_length()

bool kcenon::pacs::encoding::has_explicit_32bit_length ( vr_type vr)
nodiscardconstexprnoexcept

Checks if a VR requires 32-bit length field in Explicit VR encoding.

Parameters
vrThe VR type to check
Returns
true if the VR requires extended 32-bit length encoding

In Explicit VR encoding, these VRs have a 2-byte reserved field followed by a 4-byte length field, instead of a 2-byte length field.

See also
DICOM PS3.5 Section 7.1.2 - Data Element Structure with Explicit VR

Definition at line 235 of file vr_type.h.

235 {
236 switch (vr) {
237 case vr_type::OB: case vr_type::OD: case vr_type::OF:
238 case vr_type::OL: case vr_type::OV: case vr_type::OW:
239 case vr_type::SQ: case vr_type::SV: case vr_type::UC:
240 case vr_type::UN: case vr_type::UR: case vr_type::UT:
241 case vr_type::UV:
242 return true;
243 default:
244 return false;
245 }
246}

References OB, OD, OF, OL, OV, OW, SQ, SV, UC, UN, UR, UT, UV, and vr.

Referenced by kcenon::pacs::encoding::explicit_vr_big_endian_codec::decode_element(), kcenon::pacs::encoding::explicit_vr_codec::decode_element(), kcenon::pacs::core::dicom_file::decode_explicit_vr_be(), kcenon::pacs::core::dicom_file::decode_explicit_vr_le(), kcenon::pacs::encoding::explicit_vr_big_endian_codec::encode_element(), kcenon::pacs::encoding::explicit_vr_codec::encode_element(), kcenon::pacs::core::dicom_file::encode_explicit_vr_be(), kcenon::pacs::core::dicom_file::encode_explicit_vr_le(), and kcenon::pacs::core::dicom_file::parse_meta_information().

Here is the caller graph for this function:

◆ is_binary_vr()

bool kcenon::pacs::encoding::is_binary_vr ( vr_type vr)
nodiscardconstexprnoexcept

Checks if a VR is a binary/raw byte type.

Parameters
vrThe VR type to check
Returns
true if the VR represents raw binary data

Binary VRs include OB, OD, OF, OL, OV, OW, and UN.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/container_adapter.h.

Definition at line 196 of file vr_type.h.

196 {
197 switch (vr) {
198 case vr_type::OB: case vr_type::OD: case vr_type::OF:
199 case vr_type::OL: case vr_type::OV: case vr_type::OW:
200 case vr_type::UN:
201 return true;
202 default:
203 return false;
204 }
205}

References OB, OD, OF, OL, OV, OW, UN, and vr.

Referenced by kcenon::pacs::integration::container_adapter::maps_to_binary(), and kcenon::pacs::integration::container_adapter::to_container_value().

Here is the caller graph for this function:

◆ is_fixed_length()

bool kcenon::pacs::encoding::is_fixed_length ( vr_type vr)
nodiscardconstexprnoexcept

Checks if a VR has a fixed length.

Parameters
vrThe VR type to check
Returns
true if the VR has a fixed length

Definition at line 280 of file vr_type.h.

280 {
281 return fixed_length(vr) > 0;
282}
constexpr std::size_t fixed_length(vr_type vr) noexcept
Gets the fixed size of a VR if applicable.
Definition vr_type.h:260

References fixed_length(), and vr.

Here is the call graph for this function:

◆ is_numeric_vr()

bool kcenon::pacs::encoding::is_numeric_vr ( vr_type vr)
nodiscardconstexprnoexcept

Checks if a VR is a numeric type.

Parameters
vrThe VR type to check
Returns
true if the VR represents numeric data (binary encoded)

Numeric VRs include FL, FD, SL, SS, SV, UL, US, UV.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/container_adapter.h.

Definition at line 214 of file vr_type.h.

214 {
215 switch (vr) {
216 case vr_type::FL: case vr_type::FD:
217 case vr_type::SL: case vr_type::SS: case vr_type::SV:
218 case vr_type::UL: case vr_type::US: case vr_type::UV:
219 return true;
220 default:
221 return false;
222 }
223}

References FD, FL, SL, SS, SV, UL, US, UV, and vr.

Referenced by kcenon::pacs::core::dicom_element::as_string(), kcenon::pacs::core::dicom_file::decode_explicit_vr_be(), kcenon::pacs::core::dicom_file::encode_explicit_vr_be(), kcenon::pacs::integration::container_adapter::from_container_value(), kcenon::pacs::integration::container_adapter::maps_to_numeric(), and kcenon::pacs::integration::container_adapter::to_container_value().

Here is the caller graph for this function:

◆ is_string_vr()

bool kcenon::pacs::encoding::is_string_vr ( vr_type vr)
nodiscardconstexprnoexcept

Checks if a VR is a string type.

Parameters
vrThe VR type to check
Returns
true if the VR represents string/text data

String VRs contain character data that may need padding with spaces.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/integration/container_adapter.h.

Definition at line 175 of file vr_type.h.

175 {
176 switch (vr) {
177 case vr_type::AE: case vr_type::AS: case vr_type::CS:
178 case vr_type::DA: case vr_type::DS: case vr_type::DT:
179 case vr_type::IS: case vr_type::LO: case vr_type::LT:
180 case vr_type::PN: case vr_type::SH: case vr_type::ST:
181 case vr_type::TM: case vr_type::UC: case vr_type::UI:
182 case vr_type::UR: case vr_type::UT:
183 return true;
184 default:
185 return false;
186 }
187}

References AE, AS, CS, DA, DS, DT, IS, LO, LT, PN, SH, ST, TM, UC, UI, UR, UT, and vr.

Referenced by kcenon::pacs::core::dicom_element::as_string(), kcenon::pacs::integration::container_adapter::from_container_value(), kcenon::pacs::integration::container_adapter::get_container_type(), kcenon::pacs::integration::container_adapter::maps_to_string(), padding_char(), kcenon::pacs::core::dicom_element::remove_padding(), kcenon::pacs::integration::container_adapter::to_container_value(), validate_string(), and validate_value().

Here is the caller graph for this function:

◆ is_valid_charset()

bool kcenon::pacs::encoding::is_valid_charset ( vr_type vr,
std::string_view value )
nodiscard

Validates that a string uses only allowed characters for its VR.

Parameters
vrThe VR type
valueThe string to validate
Returns
true if all characters are valid for the VR

Character restrictions by VR type:

  • CS: A-Z, 0-9, space, underscore
  • DA: 0-9 only (YYYYMMDD format)
  • TM: 0-9, period, colon
  • UI: 0-9, period
  • DS: 0-9, +, -, ., E, e, space
  • IS: 0-9, +, -
  • AS: 0-9, D, W, M, Y
  • Other string VRs: All printable characters

Definition at line 225 of file vr_info.cpp.

225 {
226 switch (vr) {
227 case vr_type::CS:
228 // Code String: A-Z, 0-9, space, underscore
229 return std::all_of(value.begin(), value.end(), is_cs_char);
230
231 case vr_type::DA:
232 // Date: YYYYMMDD format, digits only
233 return value.size() == 8 &&
234 std::all_of(value.begin(), value.end(), is_da_char);
235
236 case vr_type::TM:
237 // Time: digits, period, colon
238 return std::all_of(value.begin(), value.end(), is_tm_char);
239
240 case vr_type::UI:
241 // UID: digits and periods only, max 64 chars
242 return value.size() <= 64 &&
243 std::all_of(value.begin(), value.end(), is_ui_char);
244
245 case vr_type::DS:
246 // Decimal String: digits, +, -, ., E, e, space
247 return std::all_of(value.begin(), value.end(), is_ds_char);
248
249 case vr_type::IS:
250 // Integer String: digits, +, -
251 return std::all_of(value.begin(), value.end(), is_is_char);
252
253 case vr_type::AS:
254 // Age String: nnnX format where X is D/W/M/Y
255 if (value.size() != 4) {
256 return false;
257 }
258 return std::all_of(value.begin(), value.end(), is_as_char) &&
259 (value[3] == 'D' || value[3] == 'W' ||
260 value[3] == 'M' || value[3] == 'Y');
261
262 case vr_type::DT:
263 // Date Time: digits, period, +, -
264 return std::all_of(value.begin(), value.end(), is_dt_char);
265
266 case vr_type::AE:
267 case vr_type::LO:
268 case vr_type::SH:
269 case vr_type::PN:
270 // These allow most printable characters but no control chars
271 // except leading/trailing spaces
272 return std::all_of(value.begin(), value.end(), is_printable);
273
274 case vr_type::LT:
275 case vr_type::ST:
276 case vr_type::UT:
277 case vr_type::UC:
278 case vr_type::UR:
279 // Text VRs allow all printable plus CR, LF, FF, TAB
280 return std::all_of(value.begin(), value.end(), is_printable);
281
282 default:
283 // Non-string VRs - charset validation not applicable
284 return true;
285 }
286}

References AE, AS, CS, DA, DS, DT, IS, LO, LT, PN, SH, ST, TM, UC, UI, UR, UT, and vr.

Referenced by validate_string(), and validate_value().

Here is the caller graph for this function:

◆ pad_to_even()

std::vector< uint8_t > kcenon::pacs::encoding::pad_to_even ( vr_type vr,
std::span< const uint8_t > data )
nodiscard

Pads data to even length as required by DICOM.

Parameters
vrThe VR type (determines padding character)
dataThe data to pad
Returns
A new vector with even-length data

DICOM requires all data element values to have even length. This function adds the appropriate padding character if needed:

  • Space (' ') for most string VRs
  • Null ('\0') for UI and binary VRs
See also
DICOM PS3.5 Section 7.1.1 - DICOM Data Element Structure

Definition at line 196 of file vr_info.cpp.

196 {
197 std::vector<uint8_t> result(data.begin(), data.end());
198
199 if (result.size() % 2 != 0) {
200 const auto& info = get_vr_info(vr);
201 result.push_back(static_cast<uint8_t>(info.padding_char));
202 }
203
204 return result;
205}

References get_vr_info(), and vr.

Referenced by kcenon::pacs::encoding::explicit_vr_big_endian_codec::encode_element(), kcenon::pacs::encoding::explicit_vr_codec::encode_element(), and kcenon::pacs::encoding::implicit_vr_codec::encode_element().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ padding_char()

char kcenon::pacs::encoding::padding_char ( vr_type vr)
nodiscardconstexprnoexcept

Gets the padding character for a VR.

Parameters
vrThe VR type to check
Returns
The padding character (' ' for most strings, '\0' for UI, 0 for binary)

DICOM requires data elements to have even length. String VRs are padded with space (' ') except for UI which is padded with null ('\0').

Definition at line 292 of file vr_type.h.

292 {
293 if (vr == vr_type::UI) {
294 return '\0'; // UI uses null padding
295 }
296 if (is_string_vr(vr)) {
297 return ' '; // Other string VRs use space padding
298 }
299 return '\0'; // Binary VRs use null padding if needed
300}

References is_string_vr(), UI, and vr.

Referenced by kcenon::pacs::core::dicom_element::apply_padding(), and kcenon::pacs::core::dicom_element::remove_padding().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ parse_specific_character_set()

specific_character_set kcenon::pacs::encoding::parse_specific_character_set ( std::string_view value)
nodiscard

Parse a Specific Character Set (0008,0005) value.

Parameters
valueThe raw attribute value (e.g., "\\ISO 2022 IR 149")
Returns
Parsed specific_character_set with resolved character set pointers

Handles multi-valued strings separated by backslash ('\'). Empty first component defaults to ISO-IR 6 (ASCII). Unknown Defined Terms are skipped with a warning.

Definition at line 471 of file character_set.cpp.

471 {
474
475 if (value.empty()) {
476 return result;
477 }
478
479 // Split by backslash
480 std::vector<std::string_view> components;
481 size_t start = 0;
482 while (start <= value.size()) {
483 size_t pos = value.find('\\', start);
484 if (pos == std::string_view::npos) {
485 components.push_back(value.substr(start));
486 break;
487 }
488 components.push_back(value.substr(start, pos - start));
489 start = pos + 1;
490 }
491
492 if (components.empty()) {
493 return result;
494 }
495
496 // First component: default character set
497 auto first = components[0];
498 // Trim whitespace
499 while (!first.empty() && first.front() == ' ') first.remove_prefix(1);
500 while (!first.empty() && first.back() == ' ') first.remove_suffix(1);
501
502 if (!first.empty()) {
503 const auto* cs = find_in_registry(first);
504 if (cs) {
505 result.default_set = cs;
506 }
507 }
508 // Empty first component: ASCII default (already set)
509
510 // Remaining components: extension character sets
511 for (size_t i = 1; i < components.size(); ++i) {
512 auto term = components[i];
513 while (!term.empty() && term.front() == ' ') term.remove_prefix(1);
514 while (!term.empty() && term.back() == ' ') term.remove_suffix(1);
515
516 if (!term.empty()) {
517 const auto* cs = find_in_registry(term);
518 if (cs) {
519 result.extension_sets.push_back(cs);
520 }
521 }
522 }
523
524 return result;
525}
const character_set_info & default_character_set() noexcept
Get the default character set (ISO-IR 6, ASCII).
Parsed representation of a multi-valued Specific Character Set.

References default_character_set(), kcenon::pacs::encoding::specific_character_set::default_set, and kcenon::pacs::encoding::specific_character_set::extension_sets.

Referenced by get_decoded_string(), and set_encoded_string().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_be16()

uint16_t kcenon::pacs::encoding::read_be16 ( const uint8_t * data)
nodiscardconstexprnoexcept

Reads a 16-bit value from big-endian bytes.

Parameters
dataPointer to at least 2 bytes
Returns
The value in native byte order

Definition at line 86 of file byte_swap.h.

86 {
87 return (static_cast<uint16_t>(data[0]) << 8) |
88 static_cast<uint16_t>(data[1]);
89}

Referenced by kcenon::pacs::encoding::explicit_vr_big_endian_codec::decode(), kcenon::pacs::encoding::explicit_vr_big_endian_codec::decode_element(), kcenon::pacs::encoding::compression::jpeg_lossless_codec::impl::decode_frame(), kcenon::pacs::encoding::explicit_vr_big_endian_codec::decode_sequence_item(), and kcenon::pacs::encoding::explicit_vr_big_endian_codec::decode_undefined_length().

Here is the caller graph for this function:

◆ read_be32()

uint32_t kcenon::pacs::encoding::read_be32 ( const uint8_t * data)
nodiscardconstexprnoexcept

Reads a 32-bit value from big-endian bytes.

Parameters
dataPointer to at least 4 bytes
Returns
The value in native byte order

Definition at line 96 of file byte_swap.h.

96 {
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}

Referenced by kcenon::pacs::encoding::explicit_vr_big_endian_codec::decode_element(), kcenon::pacs::encoding::explicit_vr_big_endian_codec::decode_sequence_item(), and kcenon::pacs::encoding::explicit_vr_big_endian_codec::decode_undefined_length().

Here is the caller graph for this function:

◆ read_be64()

uint64_t kcenon::pacs::encoding::read_be64 ( const uint8_t * data)
nodiscardconstexprnoexcept

Reads a 64-bit value from big-endian bytes.

Parameters
dataPointer to at least 8 bytes
Returns
The value in native byte order

Definition at line 108 of file byte_swap.h.

108 {
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}

◆ set_encoded_string()

void kcenon::pacs::encoding::set_encoded_string ( core::dicom_dataset & ds,
core::dicom_tag tag,
vr_type vr,
std::string_view utf8_value )

Set a string value in dataset, encoding from UTF-8.

Parameters
dsThe DICOM dataset to write to
tagThe DICOM tag
vrThe value representation
utf8_valueThe UTF-8 encoded string value

Encodes the UTF-8 input to the encoding specified by Specific Character Set (0008,0005) in the dataset, then stores the result. If no Specific Character Set is present, the value is stored as-is (ASCII assumption).

Definition at line 38 of file dataset_charset.cpp.

42 {
43
44 // Look up Specific Character Set (0008,0005)
45 auto scs_value = ds.get_string(core::tags::specific_character_set);
46 auto scs = parse_specific_character_set(scs_value);
47
48 auto encoded = encode_from_utf8(utf8_value, scs);
49 ds.insert(core::dicom_element::from_string(tag, vr, encoded));
50}
void insert(dicom_element element)
Insert or replace an element in the dataset.
std::string encode_from_utf8(std::string_view utf8_text, const specific_character_set &scs)
Encode a UTF-8 string to the target character set encoding.

References encode_from_utf8(), kcenon::pacs::core::dicom_element::from_string(), kcenon::pacs::core::dicom_dataset::get_string(), kcenon::pacs::core::dicom_dataset::insert(), parse_specific_character_set(), kcenon::pacs::core::tags::specific_character_set, and vr.

Here is the call graph for this function:

◆ split_by_escape_sequences()

std::vector< text_segment > kcenon::pacs::encoding::split_by_escape_sequences ( std::string_view text,
const specific_character_set & scs )
nodiscard

Split a string into segments by ISO 2022 escape sequences.

Parameters
textThe raw DICOM string bytes
scsThe parsed Specific Character Set configuration
Returns
Vector of text segments, each with its character set

Scans for ESC (0x1B) bytes, matches escape sequences against the configured character sets, and splits the text into segments. Segments between escape sequences inherit the previous character set.

Definition at line 531 of file character_set.cpp.

533 {
534
535 std::vector<text_segment> segments;
536
537 if (text.empty()) {
538 return segments;
539 }
540
541 // If no extensions, the entire text uses the default charset
542 if (!scs.uses_extensions()) {
543 segments.push_back({text, scs.default_set});
544 return segments;
545 }
546
547 const character_set_info* current_charset = scs.default_set;
548 size_t segment_start = 0;
549
550 for (size_t i = 0; i < text.size(); ++i) {
551 if (text[i] == ESC) {
552 // Try to match an escape sequence
553 const auto* new_charset = find_by_escape_sequence(text, i, scs);
554 if (new_charset) {
555 // Emit the segment before this escape sequence
556 if (i > segment_start) {
557 segments.push_back({
558 text.substr(segment_start, i - segment_start),
559 current_charset
560 });
561 }
562
563 // Skip the escape sequence
564 size_t esc_len = new_charset->escape_sequence.empty()
565 ? esc_ir_6.size() // ASCII return
566 : new_charset->escape_sequence.size();
567 i += esc_len - 1; // -1 because loop increments
568 segment_start = i + 1;
569 current_charset = new_charset;
570 }
571 }
572 }
573
574 // Emit the remaining segment
575 if (segment_start < text.size()) {
576 segments.push_back({
577 text.substr(segment_start),
578 current_charset
579 });
580 }
581
582 return segments;
583}

References kcenon::pacs::encoding::specific_character_set::default_set, and kcenon::pacs::encoding::specific_character_set::uses_extensions().

Referenced by decode_to_utf8().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ supported_transfer_syntaxes()

std::vector< transfer_syntax > kcenon::pacs::encoding::supported_transfer_syntaxes ( )
nodiscard

Returns a list of all supported Transfer Syntaxes.

Returns
Vector of supported transfer_syntax instances

Definition at line 380 of file transfer_syntax.cpp.

380 {
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}

◆ swap_at_bytes()

std::vector< uint8_t > kcenon::pacs::encoding::swap_at_bytes ( std::span< const uint8_t > data)
inlinenodiscard

Swaps bytes for AT (Attribute Tag) data.

Parameters
dataSpan of bytes (must be multiple of 4)
Returns
Byte-swapped copy of the data

AT consists of two 16-bit values (group, element), each needing byte swap.

Definition at line 226 of file byte_swap.h.

227 {
228 return swap_ow_bytes(data); // Each 16-bit part swapped individually
229}
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

References swap_ow_bytes().

Here is the call graph for this function:

◆ swap_fd_bytes()

std::vector< uint8_t > kcenon::pacs::encoding::swap_fd_bytes ( std::span< const uint8_t > data)
inlinenodiscard

Swaps bytes for FD (Double) value in raw data.

Parameters
dataSpan of 8 bytes
Returns
Byte-swapped copy

Definition at line 291 of file byte_swap.h.

292 {
293 return swap_od_bytes(data);
294}
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

References swap_od_bytes().

Here is the call graph for this function:

◆ swap_fl_bytes()

std::vector< uint8_t > kcenon::pacs::encoding::swap_fl_bytes ( std::span< const uint8_t > data)
inlinenodiscard

Swaps bytes for FL (Float) value in raw data.

Parameters
dataSpan of 4 bytes
Returns
Byte-swapped copy

Definition at line 281 of file byte_swap.h.

282 {
283 return swap_ol_bytes(data);
284}
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

References swap_ol_bytes().

Here is the call graph for this function:

◆ swap_od_bytes()

std::vector< uint8_t > kcenon::pacs::encoding::swap_od_bytes ( std::span< const uint8_t > data)
inlinenodiscard

Swaps bytes in-place for OD (Other Double) data.

Parameters
dataSpan of bytes (must be multiple of 8)
Returns
Byte-swapped copy of the data

OD data consists of 64-bit doubles that need individual byte swapping. Uses SIMD optimization (SSE/AVX/NEON) when available.

Definition at line 212 of file byte_swap.h.

213 {
214 std::vector<uint8_t> result(data.size());
215 simd::swap_bytes_64_simd(data.data(), result.data(), data.size());
216 return result;
217}

References kcenon::pacs::encoding::simd::swap_bytes_64_simd().

Referenced by swap_fd_bytes(), and kcenon::pacs::encoding::explicit_vr_big_endian_codec::to_big_endian().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ swap_of_bytes()

std::vector< uint8_t > kcenon::pacs::encoding::swap_of_bytes ( std::span< const uint8_t > data)
inlinenodiscard

Swaps bytes in-place for OF (Other Float) data.

Parameters
dataSpan of bytes (must be multiple of 4)
Returns
Byte-swapped copy of the data

OF data consists of 32-bit floats that need individual byte swapping.

Definition at line 199 of file byte_swap.h.

200 {
201 return swap_ol_bytes(data); // Same as OL (32-bit values)
202}

References swap_ol_bytes().

Here is the call graph for this function:

◆ swap_ol_bytes()

std::vector< uint8_t > kcenon::pacs::encoding::swap_ol_bytes ( std::span< const uint8_t > data)
inlinenodiscard

Swaps bytes in-place for OL (Other Long) data.

Parameters
dataSpan of bytes (must be multiple of 4)
Returns
Byte-swapped copy of the data

OL data consists of 32-bit values that need individual byte swapping. Uses SIMD optimization (SSE/AVX/NEON) when available.

Definition at line 185 of file byte_swap.h.

186 {
187 std::vector<uint8_t> result(data.size());
188 simd::swap_bytes_32_simd(data.data(), result.data(), data.size());
189 return result;
190}

References kcenon::pacs::encoding::simd::swap_bytes_32_simd().

Referenced by swap_fl_bytes(), swap_of_bytes(), swap_sl_bytes(), swap_ul_bytes(), and kcenon::pacs::encoding::explicit_vr_big_endian_codec::to_big_endian().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ swap_ow_bytes()

std::vector< uint8_t > kcenon::pacs::encoding::swap_ow_bytes ( std::span< const uint8_t > data)
inlinenodiscard

Swaps bytes in-place for OW (Other Word) data.

Parameters
dataSpan of bytes (must be even length)
Returns
Byte-swapped copy of the data

OW data consists of 16-bit words that need individual byte swapping. Uses SIMD optimization (SSE/AVX/NEON) when available.

Definition at line 170 of file byte_swap.h.

171 {
172 std::vector<uint8_t> result(data.size());
173 simd::swap_bytes_16_simd(data.data(), result.data(), data.size());
174 return result;
175}

References kcenon::pacs::encoding::simd::swap_bytes_16_simd().

Referenced by swap_at_bytes(), swap_ss_bytes(), swap_us_bytes(), and kcenon::pacs::encoding::explicit_vr_big_endian_codec::to_big_endian().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ swap_sl_bytes()

std::vector< uint8_t > kcenon::pacs::encoding::swap_sl_bytes ( std::span< const uint8_t > data)
inlinenodiscard

Swaps bytes for SL (Signed Long) value in raw data.

Parameters
dataSpan of 4 bytes
Returns
Byte-swapped copy

Definition at line 271 of file byte_swap.h.

272 {
273 return swap_ol_bytes(data);
274}

References swap_ol_bytes().

Here is the call graph for this function:

◆ swap_ss_bytes()

std::vector< uint8_t > kcenon::pacs::encoding::swap_ss_bytes ( std::span< const uint8_t > data)
inlinenodiscard

Swaps bytes for SS (Signed Short) value in raw data.

Parameters
dataSpan of 2 bytes
Returns
Byte-swapped copy

Definition at line 251 of file byte_swap.h.

252 {
253 return swap_ow_bytes(data);
254}

References swap_ow_bytes().

Here is the call graph for this function:

◆ swap_ul_bytes()

std::vector< uint8_t > kcenon::pacs::encoding::swap_ul_bytes ( std::span< const uint8_t > data)
inlinenodiscard

Swaps bytes for UL (Unsigned Long) value in raw data.

Parameters
dataSpan of 4 bytes
Returns
Byte-swapped copy

Definition at line 261 of file byte_swap.h.

262 {
263 return swap_ol_bytes(data);
264}

References swap_ol_bytes().

Here is the call graph for this function:

◆ swap_us_bytes()

std::vector< uint8_t > kcenon::pacs::encoding::swap_us_bytes ( std::span< const uint8_t > data)
inlinenodiscard

Swaps bytes for US (Unsigned Short) value in raw data.

Parameters
dataSpan of 2 bytes
Returns
Byte-swapped copy

Definition at line 241 of file byte_swap.h.

242 {
243 return swap_ow_bytes(data);
244}

References swap_ow_bytes().

Here is the call graph for this function:

◆ to_string()

std::string_view kcenon::pacs::encoding::to_string ( vr_type vr)
nodiscardconstexprnoexcept

Converts a vr_type to its two-character string representation.

Parameters
vrThe VR type to convert
Returns
A string_view containing the VR code (e.g., "PN", "US")

Returns "??" for unknown or invalid VR types.

Examples
/home/runner/work/pacs_system/pacs_system/include/kcenon/pacs/services/pir/patient_reconciliation_service.h.

Definition at line 83 of file vr_type.h.

83 {
84 switch (vr) {
85 // String VRs
86 case vr_type::AE: return "AE";
87 case vr_type::AS: return "AS";
88 case vr_type::CS: return "CS";
89 case vr_type::DA: return "DA";
90 case vr_type::DS: return "DS";
91 case vr_type::DT: return "DT";
92 case vr_type::IS: return "IS";
93 case vr_type::LO: return "LO";
94 case vr_type::LT: return "LT";
95 case vr_type::PN: return "PN";
96 case vr_type::SH: return "SH";
97 case vr_type::ST: return "ST";
98 case vr_type::TM: return "TM";
99 case vr_type::UC: return "UC";
100 case vr_type::UI: return "UI";
101 case vr_type::UR: return "UR";
102 case vr_type::UT: return "UT";
103 // Numeric VRs
104 case vr_type::FL: return "FL";
105 case vr_type::FD: return "FD";
106 case vr_type::SL: return "SL";
107 case vr_type::SS: return "SS";
108 case vr_type::UL: return "UL";
109 case vr_type::US: return "US";
110 // Binary VRs
111 case vr_type::OB: return "OB";
112 case vr_type::OD: return "OD";
113 case vr_type::OF: return "OF";
114 case vr_type::OL: return "OL";
115 case vr_type::OV: return "OV";
116 case vr_type::OW: return "OW";
117 case vr_type::UN: return "UN";
118 // Special VRs
119 case vr_type::AT: return "AT";
120 case vr_type::SQ: return "SQ";
121 case vr_type::SV: return "SV";
122 case vr_type::UV: return "UV";
123 default: return "??";
124 }
125}

References AE, AS, AT, CS, DA, DS, DT, FD, FL, IS, LO, LT, OB, OD, OF, OL, OV, OW, PN, SH, SL, SQ, SS, ST, SV, TM, UC, UI, UL, UN, UR, US, UT, UV, and vr.

Referenced by kcenon::pacs::core::dicom_file::decode_implicit_vr_le(), kcenon::pacs::encoding::explicit_vr_big_endian_codec::encode_element(), kcenon::pacs::encoding::explicit_vr_codec::encode_element(), kcenon::pacs::core::dicom_file::encode_explicit_vr_be(), kcenon::pacs::core::dicom_file::encode_explicit_vr_le(), and kcenon::pacs::integration::container_adapter::make_element_key().

Here is the caller graph for this function:

◆ trim_padding()

std::string kcenon::pacs::encoding::trim_padding ( vr_type vr,
std::string_view value )
nodiscard

Removes trailing padding characters from a string value.

Parameters
vrThe VR type (determines padding character to remove)
valueThe value to trim
Returns
A string with trailing padding removed

Removes:

  • Trailing spaces for most string VRs
  • Trailing nulls for UI VR

Definition at line 207 of file vr_info.cpp.

207 {
208 if (value.empty()) {
209 return std::string{};
210 }
211
212 const auto& info = get_vr_info(vr);
213 char pad = info.padding_char;
214
215 // Find the last non-padding character
216 auto end = value.find_last_not_of(pad);
217 if (end == std::string_view::npos) {
218 // All characters are padding
219 return std::string{};
220 }
221
222 return std::string{value.substr(0, end + 1)};
223}

References get_vr_info(), and vr.

Here is the call graph for this function:

◆ validate_string()

bool kcenon::pacs::encoding::validate_string ( vr_type vr,
std::string_view value )
nodiscard

Validates a string value against VR encoding rules.

Parameters
vrThe VR type for validation
valueThe string value to validate
Returns
true if the string conforms to VR requirements

Validates string VRs for:

  • Maximum length
  • Allowed character sets
  • Format patterns (dates, times, UIDs, etc.)

Definition at line 170 of file vr_info.cpp.

170 {
171 const auto& info = get_vr_info(vr);
172
173 // Non-string VRs cannot be validated as strings
174 if (!is_string_vr(vr)) {
175 return false;
176 }
177
178 // Check maximum length
179 if (info.max_length != 0xFFFFFFFE) {
180 if (value.size() > info.max_length) {
181 return false;
182 }
183 }
184
185 // Fixed-length string VRs (AS, DA) must match exact length
186 if (info.is_fixed_length && info.fixed_size > 0) {
187 if (value.size() != info.fixed_size) {
188 return false;
189 }
190 }
191
192 // Validate character set
193 return is_valid_charset(vr, value);
194}
constexpr bool is_string_vr(vr_type vr) noexcept
Checks if a VR is a string type.
Definition vr_type.h:175
bool is_valid_charset(vr_type vr, std::string_view value)
Validates that a string uses only allowed characters for its VR.
Definition vr_info.cpp:225

References get_vr_info(), is_string_vr(), is_valid_charset(), and vr.

Here is the call graph for this function:

◆ validate_value()

bool kcenon::pacs::encoding::validate_value ( vr_type vr,
std::span< const uint8_t > data )
nodiscard

Validates binary data against VR encoding rules.

Parameters
vrThe VR type for validation
dataThe binary data to validate
Returns
true if the data conforms to VR requirements

Performs VR-specific validation including:

  • Length constraints
  • Character set restrictions
  • Format requirements (for structured VRs like DA, TM)

Definition at line 141 of file vr_info.cpp.

141 {
142 const auto& info = get_vr_info(vr);
143
144 // For fixed-length VRs, check that size is a multiple of fixed_size (VM >= 1)
145 if (info.is_fixed_length && info.fixed_size > 0) {
146 if (data.size() % info.fixed_size != 0) {
147 return false;
148 }
149 // Fixed-length VRs pass validation if size is correct multiple
150 return true;
151 }
152
153 // Check maximum length for variable-length VRs (0xFFFFFFFE means unlimited)
154 if (info.max_length != 0xFFFFFFFE && info.max_length != 0xFFFFFFFF) {
155 if (data.size() > info.max_length) {
156 return false;
157 }
158 }
159
160 // String VRs need character validation
161 if (is_string_vr(vr)) {
162 std::string_view str_value(reinterpret_cast<const char*>(data.data()),
163 data.size());
164 return is_valid_charset(vr, str_value);
165 }
166
167 return true;
168}

References get_vr_info(), is_string_vr(), is_valid_charset(), and vr.

Here is the call graph for this function:

◆ write_be16()

void kcenon::pacs::encoding::write_be16 ( std::vector< uint8_t > & buffer,
uint16_t value )
inline

Writes a 16-bit value in big-endian byte order.

Parameters
bufferBuffer to append to
valueThe value to write

Definition at line 124 of file byte_swap.h.

124 {
125 buffer.push_back(static_cast<uint8_t>((value >> 8) & 0xFF));
126 buffer.push_back(static_cast<uint8_t>(value & 0xFF));
127}

Referenced by kcenon::pacs::encoding::explicit_vr_big_endian_codec::encode_element(), kcenon::pacs::encoding::explicit_vr_big_endian_codec::encode_sequence(), kcenon::pacs::encoding::explicit_vr_big_endian_codec::encode_sequence_item(), kcenon::pacs::encoding::compression::jpeg_lossless_codec::impl::write_dht(), kcenon::pacs::encoding::compression::jpeg_lossless_codec::impl::write_sof3(), and kcenon::pacs::encoding::compression::jpeg_lossless_codec::impl::write_sos().

Here is the caller graph for this function:

◆ write_be32()

void kcenon::pacs::encoding::write_be32 ( std::vector< uint8_t > & buffer,
uint32_t value )
inline

Writes a 32-bit value in big-endian byte order.

Parameters
bufferBuffer to append to
valueThe value to write

Definition at line 134 of file byte_swap.h.

134 {
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}

Referenced by kcenon::pacs::encoding::explicit_vr_big_endian_codec::encode_element(), kcenon::pacs::encoding::explicit_vr_big_endian_codec::encode_sequence(), and kcenon::pacs::encoding::explicit_vr_big_endian_codec::encode_sequence_item().

Here is the caller graph for this function:

◆ write_be64()

void kcenon::pacs::encoding::write_be64 ( std::vector< uint8_t > & buffer,
uint64_t value )
inline

Writes a 64-bit value in big-endian byte order.

Parameters
bufferBuffer to append to
valueThe value to write

Definition at line 146 of file byte_swap.h.

146 {
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}