0
|
1 /**
|
|
2 * Orthanc - A Lightweight, RESTful DICOM Store
|
|
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
|
|
4 * Department, University Hospital of Liege, Belgium
|
|
5 *
|
|
6 * This program is free software: you can redistribute it and/or
|
|
7 * modify it under the terms of the GNU Affero General Public License
|
|
8 * as published by the Free Software Foundation, either version 3 of
|
|
9 * the License, or (at your option) any later version.
|
|
10 *
|
|
11 * This program is distributed in the hope that it will be useful, but
|
|
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
14 * Affero General Public License for more details.
|
|
15 *
|
|
16 * You should have received a copy of the GNU Affero General Public License
|
|
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
18 **/
|
|
19
|
|
20
|
|
21 #include "DicomToolbox.h"
|
|
22
|
|
23 #include "Orthanc/Core/Logging.h"
|
|
24 #include "Orthanc/Core/OrthancException.h"
|
|
25 #include "Orthanc/Core/Toolbox.h"
|
|
26
|
|
27 #if ORTHANC_ENABLE_DCMTK == 1
|
|
28 # include <dcmtk/dcmdata/dcelem.h>
|
|
29 # include <dcmtk/dcmdata/dcsequen.h>
|
|
30 #endif
|
|
31
|
|
32 #include <boost/lexical_cast.hpp>
|
|
33
|
|
34 namespace OrthancWSI
|
|
35 {
|
|
36 namespace DicomToolbox
|
|
37 {
|
|
38 #if ORTHANC_ENABLE_DCMTK == 1
|
|
39 void SetStringTag(DcmItem& dataset,
|
|
40 const DcmTagKey& key,
|
|
41 const std::string& value)
|
|
42 {
|
|
43 if (!dataset.tagExists(key) &&
|
|
44 !dataset.putAndInsertString(key, value.c_str()).good())
|
|
45 {
|
|
46 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
|
|
47 }
|
|
48 }
|
|
49
|
|
50 void SetUint16Tag(DcmItem& dataset,
|
|
51 const DcmTagKey& key,
|
|
52 uint16_t value)
|
|
53 {
|
|
54 if (!dataset.tagExists(key) &&
|
|
55 !dataset.putAndInsertUint16(key, value).good())
|
|
56 {
|
|
57 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
|
|
58 }
|
|
59 }
|
|
60
|
|
61
|
|
62 void SetUint32Tag(DcmItem& dataset,
|
|
63 const DcmTagKey& key,
|
|
64 uint32_t value)
|
|
65 {
|
|
66 if (!dataset.tagExists(key) &&
|
|
67 !dataset.putAndInsertUint32(key, value).good())
|
|
68 {
|
|
69 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
|
|
70 }
|
|
71 }
|
|
72
|
|
73
|
|
74 DcmItem* ExtractSingleSequenceItem(DcmItem& dataset,
|
|
75 const DcmTagKey& key)
|
|
76 {
|
|
77 DcmElement* element = NULL;
|
|
78 if (!const_cast<DcmItem&>(dataset).findAndGetElement(key, element).good() ||
|
|
79 element == NULL)
|
|
80 {
|
|
81 return NULL;
|
|
82 }
|
|
83
|
|
84 if (element->getVR() != EVR_SQ)
|
|
85 {
|
|
86 DcmTag tag(key);
|
|
87 LOG(ERROR) << "The following element in the DICOM dataset is not a sequence as expected: " << tag.getTagName();
|
|
88 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
|
|
89 }
|
|
90
|
|
91 DcmSequenceOfItems& sequence = dynamic_cast<DcmSequenceOfItems&>(*element);
|
|
92 if (sequence.card() != 1)
|
|
93 {
|
|
94 LOG(ERROR) << "Bad number of elements in the sequence (it must contain exactly 1 element)";
|
|
95 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
|
|
96 }
|
|
97
|
|
98 return sequence.getItem(0);
|
|
99 }
|
|
100
|
|
101
|
|
102 uint16_t GetUint16Tag(DcmItem& dataset,
|
|
103 const DcmTagKey& key)
|
|
104 {
|
|
105 uint16_t value;
|
|
106 if (dataset.findAndGetUint16(key, value).good())
|
|
107 {
|
|
108 return value;
|
|
109 }
|
|
110 else
|
|
111 {
|
|
112 throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentTag);
|
|
113 }
|
|
114 }
|
|
115
|
|
116
|
|
117 uint32_t GetUint32Tag(DcmItem& dataset,
|
|
118 const DcmTagKey& key)
|
|
119 {
|
|
120 Uint32 value;
|
|
121 if (dataset.findAndGetUint32(key, value).good())
|
|
122 {
|
|
123 return value;
|
|
124 }
|
|
125 else
|
|
126 {
|
|
127 throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentTag);
|
|
128 }
|
|
129 }
|
|
130
|
|
131
|
|
132 int32_t GetInt32Tag(DcmItem& dataset,
|
|
133 const DcmTagKey& key)
|
|
134 {
|
|
135 Sint32 value;
|
|
136 if (dataset.findAndGetSint32(key, value).good())
|
|
137 {
|
|
138 return value;
|
|
139 }
|
|
140 else
|
|
141 {
|
|
142 throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentTag);
|
|
143 }
|
|
144 }
|
|
145
|
|
146
|
|
147 std::string GetStringTag(DcmItem& dataset,
|
|
148 const DcmTagKey& key)
|
|
149 {
|
|
150 const char* value = NULL;
|
|
151 if (dataset.findAndGetString(key, value).good() &&
|
|
152 value != NULL)
|
|
153 {
|
|
154 return Orthanc::Toolbox::StripSpaces(value);
|
|
155 }
|
|
156 else
|
|
157 {
|
|
158 throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentTag);
|
|
159 }
|
|
160 }
|
|
161 #endif
|
|
162
|
|
163
|
|
164 bool GetStringTag(std::string& result,
|
|
165 const Json::Value& simplifiedTags,
|
|
166 const std::string& tagName,
|
|
167 const std::string& defaultValue)
|
|
168 {
|
|
169 if (simplifiedTags.type() != Json::objectValue)
|
|
170 {
|
|
171 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
|
|
172 }
|
|
173
|
|
174 if (!simplifiedTags.isMember(tagName))
|
|
175 {
|
|
176 result = defaultValue;
|
|
177 return false;
|
|
178 }
|
|
179 else if (simplifiedTags[tagName].type() != Json::stringValue)
|
|
180 {
|
|
181 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
|
|
182 }
|
|
183 else
|
|
184 {
|
|
185 result = simplifiedTags[tagName].asString();
|
|
186 return true;
|
|
187 }
|
|
188 }
|
|
189
|
|
190
|
|
191 std::string GetMandatoryStringTag(const Json::Value& simplifiedTags,
|
|
192 const std::string& tagName)
|
|
193 {
|
|
194 std::string s;
|
|
195 if (GetStringTag(s, simplifiedTags, tagName, ""))
|
|
196 {
|
|
197 return s;
|
|
198 }
|
|
199 else
|
|
200 {
|
|
201 throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentTag);
|
|
202 }
|
|
203 }
|
|
204
|
|
205
|
|
206 const Json::Value& GetSequenceTag(const Json::Value& simplifiedTags,
|
|
207 const std::string& tagName)
|
|
208 {
|
|
209 if (simplifiedTags.type() != Json::objectValue ||
|
|
210 !simplifiedTags.isMember(tagName) ||
|
|
211 simplifiedTags[tagName].type() != Json::arrayValue)
|
|
212 {
|
|
213 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
|
|
214 }
|
|
215
|
|
216 return simplifiedTags[tagName];
|
|
217 }
|
|
218
|
|
219
|
|
220 int GetIntegerTag(const Json::Value& simplifiedTags,
|
|
221 const std::string& tagName)
|
|
222 {
|
|
223 try
|
|
224 {
|
|
225 std::string s = Orthanc::Toolbox::StripSpaces(GetMandatoryStringTag(simplifiedTags, tagName));
|
|
226 return boost::lexical_cast<int>(s);
|
|
227 }
|
|
228 catch (boost::bad_lexical_cast&)
|
|
229 {
|
|
230 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadFileFormat);
|
|
231 }
|
|
232 }
|
|
233
|
|
234
|
|
235 unsigned int GetUnsignedIntegerTag(const Json::Value& simplifiedTags,
|
|
236 const std::string& tagName)
|
|
237 {
|
|
238 int value = GetIntegerTag(simplifiedTags, tagName);
|
|
239
|
|
240 if (value >= 0)
|
|
241 {
|
|
242 return static_cast<unsigned int>(value);
|
|
243 }
|
|
244 else
|
|
245 {
|
|
246 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
|
|
247 }
|
|
248 }
|
|
249 }
|
|
250 }
|