GCC Code Coverage Report


./
File: libs/io/dicom/helper/dicom_data_reader.hxx
Date: 2025-01-21 16:21:04
Lines:
18/24
75.0%
Functions:
280/281
99.6%
Branches:
20/50
40.0%

Line Branch Exec Source
1 /************************************************************************
2 *
3 * Copyright (C) 2017-2024 IRCAD France
4 * Copyright (C) 2017 IHU Strasbourg
5 *
6 * This file is part of Sight.
7 *
8 * Sight is free software: you can redistribute it and/or modify it under
9 * the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * Sight is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with Sight. If not, see <https://www.gnu.org/licenses/>.
20 *
21 ***********************************************************************/
22
23 #pragma once
24
25 #include <sight/io/dicom/config.hpp>
26
27 #include "io/dicom/helper/encoding.hpp"
28
29 #include <core/log/logger.hpp>
30
31 #include <gdcmAttribute.h>
32 #include <gdcmDataSet.h>
33
34 namespace sight::io::dicom::helper
35 {
36
37 /**
38 * @brief This class contains helpers to handle GDCM data reading.
39 */
40 class SIGHT_IO_DICOM_CLASS_API dicom_data_reader
41 {
42 public:
43
44 /**
45 * @brief Return a string from a tag found in \p dataset.
46 * An empty string returned means the tag is not found or empty.
47 * The value is returned without binary space padding.
48 * @tparam GROUP Group of the tag
49 * @tparam ELEMENT Element of the tag
50 * @param[in] _dataset Data set containing the tag
51 * @param[in] _charset Specific Character Set (if empty assuming ASCII).
52 * @param[in] _logger Logger used for encoding issue
53 * @note charset shall be set if SpecificCharacterSet (0008,0005) is
54 * defined and tag's VR is SH, LO, ST, PN, LT or UT.
55 * @return The tag value as string
56 */
57 template<std::uint16_t GROUP, std::uint16_t ELEMENT>
58
2/2
✓ Branch 0 taken 42926 times.
✓ Branch 1 taken 102345 times.
290517 static std::string get_tag_value(
59 const gdcm::DataSet& _dataset,
60 const std::string& _charset = "",
61 const core::log::logger::sptr& _logger = nullptr
62 )
63 {
64
2/2
✓ Branch 0 taken 42926 times.
✓ Branch 1 taken 102345 times.
290517 std::string result;
65
66 290517 const gdcm::Tag tag(GROUP, ELEMENT);
67
68
2/2
✓ Branch 0 taken 42926 times.
✓ Branch 1 taken 102345 times.
290517 if(_dataset.FindDataElement(tag))
69 {
70
1/2
✓ Branch 1 taken 42926 times.
✗ Branch 2 not taken.
85836 const gdcm::DataElement& data_element = _dataset.GetDataElement(tag);
71
72
2/2
✓ Branch 0 taken 40810 times.
✓ Branch 1 taken 2116 times.
85836 if(!data_element.IsEmpty()) // Can be type 2
73 {
74 // Retrieve buffer
75 81609 const gdcm::ByteValue* bv = data_element.GetByteValue();
76
77
1/2
✓ Branch 0 taken 40810 times.
✗ Branch 1 not taken.
81609 if(bv)
78 {
79
4/8
✓ Branch 1 taken 40810 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 40810 times.
✗ Branch 4 not taken.
✓ Branch 6 taken 40810 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 40810 times.
✗ Branch 10 not taken.
163218 std::string buffer(bv->GetPointer(), bv->GetLength());
80
81 // Trim buffer
82
1/2
✓ Branch 1 taken 40810 times.
✗ Branch 2 not taken.
81609 const std::string trimmed_buffer = gdcm::LOComp::Trim(buffer.c_str());
83
84 try
85 {
86
1/2
✓ Branch 1 taken 40810 times.
✗ Branch 2 not taken.
81609 result = io::dicom::helper::encoding::convert_string(trimmed_buffer, _charset, _logger);
87 }
88 catch(const std::runtime_error& e)
89 {
90 if(_logger)
91 {
92 std::stringstream ss;
93 ss << "Could not read tag " << tag << " : " << e.what();
94 _logger->warning(ss.str());
95 }
96
97 result = trimmed_buffer;
98 }
99 81609 }
100 }
101 }
102
103 290517 return result;
104 }
105
106 /**
107 * @brief Return an utf-8 tag value from the tag value's buffer
108 * @tparam GROUP Group of the tag
109 * @tparam ELEMENT Element of the tag
110 * @param[in] _buffer Tag value's buffer
111 * @param[in] _charset Specific Character Set (if empty assuming ASCII).
112 * @param[in] _logger Logger used for encoding issue
113 * @note charset shall be set if SpecificCharacterSet (0008,0005) is
114 * defined and tag's VR is SH, LO, ST, PN, LT or UT.
115 * @return The tag value as string
116 */
117 template<std::uint16_t GROUP, std::uint16_t ELEMENT>
118 static std::string get_tag_value(
119 const std::string& _buffer,
120 const std::string& _charset = "",
121 const core::log::logger::sptr& _logger = nullptr
122 )
123 {
124 std::string result;
125
126 const gdcm::Tag tag = gdcm::Attribute<GROUP, ELEMENT>::GetTag();
127
128 // Trim buffer
129 const std::string trimmed_buffer = gdcm::LOComp::Trim(_buffer.c_str());
130
131 try
132 {
133 result = io::dicom::helper::encoding::convert_string(trimmed_buffer, _charset, _logger);
134 }
135 catch(const std::runtime_error& e)
136 {
137 if(_logger)
138 {
139 std::stringstream ss;
140 ss << "Could not read tag " << tag << " : " << e.what();
141 _logger->warning(ss.str());
142 }
143
144 result = trimmed_buffer;
145 }
146
147 return result;
148 }
149
150 /**
151 * @brief Return a value from a tag found in dataset.
152 * @tparam GROUP Group of the tag.
153 * @tparam ELEMENT Element of the tag.
154 * @tparam T Type of value.
155 * @param[in] _dataset Data set of tags.
156 * @return The tag value.
157 */
158 template<std::uint16_t GROUP, std::uint16_t ELEMENT, typename T>
159
1/2
✓ Branch 1 taken 9 times.
✗ Branch 2 not taken.
3438 static T get_tag_value(const gdcm::DataSet& _dataset)
160 {
161 3438 gdcm::Attribute<GROUP, ELEMENT> attribute {};
162
2/4
✓ Branch 1 taken 1721 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1712 times.
✗ Branch 5 not taken.
1726 attribute.SetFromDataSet(_dataset);
163
1/2
✓ Branch 1 taken 1712 times.
✗ Branch 2 not taken.
1726 return attribute.GetValue();
164 14 }
165 };
166
167 } // namespace sight::io::dicom::helper
168