47 std::cout <<
"DICOM tags are the fundamental identifiers for data elements.\n";
48 std::cout <<
"Each tag is a (Group, Element) pair of 16-bit hexadecimal numbers.\n\n";
54 std::cout <<
"Patient Name Tag: " << patient_name_tag.
to_string() <<
"\n";
55 std::cout <<
" Group: 0x" << std::hex << std::setw(4) << std::setfill(
'0')
56 << patient_name_tag.group() << std::dec <<
"\n";
57 std::cout <<
" Element: 0x" << std::hex << std::setw(4) << std::setfill(
'0')
58 << patient_name_tag.element() << std::dec <<
"\n";
59 std::cout <<
" Private? " << (patient_name_tag.is_private() ?
"Yes" :
"No") <<
"\n\n";
62 auto parsed = core::dicom_tag::from_string(
"(0008,0020)");
64 std::cout <<
"Parsed Study Date tag from string: " << parsed->to_string() <<
"\n";
68 std::cout <<
"\nTag comparison:\n";
69 std::cout <<
" (0010,0010) == tags::patient_name? "
70 << (patient_name_tag == tags::patient_name ?
"Yes" :
"No") <<
"\n";
82 std::cout <<
"A DICOM dataset is an ordered collection of data elements.\n";
83 std::cout <<
"Each element consists of: Tag + VR + Value\n\n";
85 std::cout <<
"Common VR (Value Representation) types:\n";
86 std::cout <<
" PN = Person Name DA = Date TM = Time\n";
87 std::cout <<
" LO = Long String SH = Short String CS = Code String\n";
88 std::cout <<
" UI = Unique ID US = Unsigned Short IS = Integer String\n\n";
94 dataset.
set_string(tags::patient_name, enc::vr_type::PN,
"DOE^JOHN^M");
95 dataset.
set_string(tags::patient_id, enc::vr_type::LO,
"PAT001");
96 dataset.
set_string(tags::patient_birth_date, enc::vr_type::DA,
"19850315");
97 dataset.
set_string(tags::patient_sex, enc::vr_type::CS,
"M");
100 dataset.
set_string(tags::study_date, enc::vr_type::DA,
"20240115");
101 dataset.
set_string(tags::study_time, enc::vr_type::TM,
"143022");
102 dataset.
set_string(tags::study_description, enc::vr_type::LO,
"CT CHEST W/CONTRAST");
103 dataset.
set_string(tags::accession_number, enc::vr_type::SH,
"ACC123456");
106 dataset.
set_string(tags::modality, enc::vr_type::CS,
"CT");
107 dataset.
set_string(tags::series_description, enc::vr_type::LO,
"AXIAL 3mm");
108 dataset.
set_numeric<uint32_t>(tags::series_number, enc::vr_type::IS, 1);
109 dataset.
set_numeric<uint32_t>(tags::instance_number, enc::vr_type::IS, 1);
113 dataset.
set_string(tags::study_instance_uid, enc::vr_type::UI,
114 "1.2.410.200001.1.1.20240115.143022.1");
115 dataset.
set_string(tags::series_instance_uid, enc::vr_type::UI,
116 "1.2.410.200001.1.1.20240115.143022.1.1");
117 dataset.
set_string(tags::sop_class_uid, enc::vr_type::UI,
118 "1.2.840.10008.5.1.4.1.1.2");
119 dataset.
set_string(tags::sop_instance_uid, enc::vr_type::UI,
120 "1.2.410.200001.1.1.20240115.143022.1.1.1");
124 dataset.
set_numeric<uint16_t>(tags::rows, enc::vr_type::US, 512);
125 dataset.
set_numeric<uint16_t>(tags::columns, enc::vr_type::US, 512);
126 dataset.
set_numeric<uint16_t>(tags::bits_allocated, enc::vr_type::US, 16);
127 dataset.
set_numeric<uint16_t>(tags::bits_stored, enc::vr_type::US, 12);
128 dataset.
set_numeric<uint16_t>(tags::high_bit, enc::vr_type::US, 11);
129 dataset.
set_numeric<uint16_t>(tags::pixel_representation, enc::vr_type::US, 0);
130 dataset.
set_numeric<uint16_t>(tags::samples_per_pixel, enc::vr_type::US, 1);
131 dataset.
set_string(tags::photometric_interpretation, enc::vr_type::CS,
"MONOCHROME2");
134 std::cout <<
"Dataset created with " << dataset.
size() <<
" elements:\n\n";
137 {
"Name", dataset.
get_string(tags::patient_name)},
139 {
"Birth Date", dataset.
get_string(tags::patient_birth_date)},
140 {
"Sex", dataset.
get_string(tags::patient_sex)}
144 {
"Date", dataset.
get_string(tags::study_date)},
145 {
"Description", dataset.
get_string(tags::study_description)},
146 {
"Modality", dataset.
get_string(tags::modality)},
147 {
"Accession", dataset.
get_string(tags::accession_number)}
151 auto rows_val = dataset.
get_numeric<uint16_t>(tags::rows);
152 auto cols_val = dataset.
get_numeric<uint16_t>(tags::columns);
153 std::cout <<
"\nImage dimensions: "
154 << rows_val.value_or(0) <<
" x " << cols_val.value_or(0) <<
" pixels\n";
169 std::cout <<
"DICOM Part 10 file structure:\n";
170 std::cout <<
" 1. 128-byte preamble (typically zeros)\n";
171 std::cout <<
" 2. 'DICM' magic number\n";
172 std::cout <<
" 3. File Meta Information (always Explicit VR Little Endian)\n";
173 std::cout <<
" 4. Dataset (encoded per Transfer Syntax)\n\n";
177 auto dicom_file = core::dicom_file::create(
179 enc::transfer_syntax::explicit_vr_little_endian);
181 std::cout <<
"Transfer Syntax: "
182 << dicom_file.transfer_syntax().name() <<
"\n\n";
185 const std::string output_path =
"hello_dicom_output.dcm";
186 auto save_result = dicom_file.save(output_path);
188 if (save_result.is_ok()) {
201 auto read_result = core::dicom_file::open(output_path);
203 if (read_result.is_ok()) {
204 auto& loaded_file = read_result.value();
205 const auto& loaded_ds = loaded_file.dataset();
209 std::cout <<
"\nFile properties:\n";
210 std::cout <<
" Transfer Syntax: " << loaded_file.transfer_syntax().name() <<
"\n";
211 std::cout <<
" SOP Class UID: " << loaded_file.sop_class_uid() <<
"\n";
212 std::cout <<
" Element count: " << loaded_ds.size() <<
"\n\n";
215 std::cout <<
"All elements in the dataset:\n";
216 std::cout << std::string(60,
'-') <<
"\n";
218 for (
const auto& [tag, element] : loaded_ds) {
219 auto value_result = element.as_string();
220 std::string value_str = value_result.is_ok()
221 ? value_result.value()
225 if (value_str.length() > 40) {
226 value_str = value_str.substr(0, 37) +
"...";
229 std::cout << tag.to_string() <<
" "
231 << value_str <<
"\n";
233 std::cout << std::string(60,
'-') <<
"\n";
247 "Congratulations! You have learned:",
249 "1. DICOM Tags - (Group, Element) pairs that identify data",
250 "2. Value Representations - Data types like PN, DA, UI, US",
251 "3. DICOM Dataset - Ordered collection of elements",
252 "4. DICOM File - Part 10 format for file storage",
254 "Next step: Level 2 - Echo Server (DICOM networking)"
257 std::cout <<
"\nYou can verify the output file with DCMTK:\n";
258 std::cout <<
" dcmdump " << output_path <<
"\n\n";