comparison OrthancServer/FromDcmtkBridge.cpp @ 1657:5360cdba70d8

New function "OrthancPluginRegisterDictionaryTag()" to declare DICOM tags
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 29 Sep 2015 16:31:48 +0200
parents d3ba98d6b6e9
children 14a32b2fa63e
comparison
equal deleted inserted replaced
1656:d3ba98d6b6e9 1657:5360cdba70d8
155 } 155 }
156 156
157 #endif 157 #endif
158 158
159 159
160 namespace
161 {
162 class DictionaryLocker
163 {
164 private:
165 DcmDataDictionary& dictionary_;
166
167 public:
168 DictionaryLocker() : dictionary_(dcmDataDict.wrlock())
169 {
170 }
171
172 ~DictionaryLocker()
173 {
174 dcmDataDict.unlock();
175 }
176
177 DcmDataDictionary& operator*()
178 {
179 return dictionary_;
180 }
181
182 DcmDataDictionary* operator->()
183 {
184 return &dictionary_;
185 }
186 };
187 }
188
189
160 void FromDcmtkBridge::InitializeDictionary() 190 void FromDcmtkBridge::InitializeDictionary()
161 { 191 {
162 /* Disable "gethostbyaddr" (which results in memory leaks) and use raw IP addresses */ 192 /* Disable "gethostbyaddr" (which results in memory leaks) and use raw IP addresses */
163 dcmDisableGethostbyaddr.set(OFTrue); 193 dcmDisableGethostbyaddr.set(OFTrue);
164 194
165 dcmDataDict.clear(); 195 {
166 DcmDataDictionary& d = dcmDataDict.wrlock(); 196 DictionaryLocker locker;
197
198 locker->clear();
167 199
168 #if DCMTK_USE_EMBEDDED_DICTIONARIES == 1 200 #if DCMTK_USE_EMBEDDED_DICTIONARIES == 1
169 LOG(WARNING) << "Loading the embedded dictionaries"; 201 LOG(WARNING) << "Loading the embedded dictionaries";
170 /** 202 /**
171 * Do not load DICONDE dictionary, it breaks the other tags. The 203 * Do not load DICONDE dictionary, it breaks the other tags. The
172 * command "strace storescu 2>&1 |grep dic" shows that DICONDE 204 * command "strace storescu 2>&1 |grep dic" shows that DICONDE
173 * dictionary is not loaded by storescu. 205 * dictionary is not loaded by storescu.
174 **/ 206 **/
175 //LoadEmbeddedDictionary(d, EmbeddedResources::DICTIONARY_DICONDE); 207 //LoadEmbeddedDictionary(*locker, EmbeddedResources::DICTIONARY_DICONDE);
176 208
177 LoadEmbeddedDictionary(d, EmbeddedResources::DICTIONARY_DICOM); 209 LoadEmbeddedDictionary(*locker, EmbeddedResources::DICTIONARY_DICOM);
178 LoadEmbeddedDictionary(d, EmbeddedResources::DICTIONARY_PRIVATE); 210 LoadEmbeddedDictionary(*locker, EmbeddedResources::DICTIONARY_PRIVATE);
179 211
180 #elif defined(__linux) || defined(__FreeBSD_kernel__) 212 #elif defined(__linux) || defined(__FreeBSD_kernel__)
181 std::string path = DCMTK_DICTIONARY_DIR; 213 std::string path = DCMTK_DICTIONARY_DIR;
182 214
183 const char* env = std::getenv(DCM_DICT_ENVIRONMENT_VARIABLE); 215 const char* env = std::getenv(DCM_DICT_ENVIRONMENT_VARIABLE);
184 if (env != NULL) 216 if (env != NULL)
185 { 217 {
186 path = std::string(env); 218 path = std::string(env);
187 } 219 }
188 220
189 LoadExternalDictionary(d, path, "dicom.dic"); 221 LoadExternalDictionary(*locker, path, "dicom.dic");
190 LoadExternalDictionary(d, path, "private.dic"); 222 LoadExternalDictionary(*locker, path, "private.dic");
191 223
192 #else 224 #else
193 #error Support your platform here 225 #error Support your platform here
194 #endif 226 #endif
195 227 }
196 dcmDataDict.unlock();
197 228
198 /* make sure data dictionary is loaded */ 229 /* make sure data dictionary is loaded */
199 if (!dcmDataDict.isDictionaryLoaded()) 230 if (!dcmDataDict.isDictionaryLoaded())
200 { 231 {
201 LOG(ERROR) << "No DICOM dictionary loaded, check environment variable: " << DCM_DICT_ENVIRONMENT_VARIABLE; 232 LOG(ERROR) << "No DICOM dictionary loaded, check environment variable: " << DCM_DICT_ENVIRONMENT_VARIABLE;
208 if (key.getEVR() != EVR_DS) 239 if (key.getEVR() != EVR_DS)
209 { 240 {
210 LOG(ERROR) << "The DICOM dictionary has not been correctly read"; 241 LOG(ERROR) << "The DICOM dictionary has not been correctly read";
211 throw OrthancException(ErrorCode_InternalError); 242 throw OrthancException(ErrorCode_InternalError);
212 } 243 }
244 }
245 }
246
247
248 void FromDcmtkBridge::RegisterDictionaryTag(const DicomTag& tag,
249 const DcmEVR& vr,
250 const std::string& name,
251 unsigned int minMultiplicity,
252 unsigned int maxMultiplicity)
253 {
254 if (minMultiplicity < 1)
255 {
256 throw OrthancException(ErrorCode_ParameterOutOfRange);
257 }
258
259 if (maxMultiplicity == 0)
260 {
261 maxMultiplicity = DcmVariableVM;
262 }
263 else if (maxMultiplicity < minMultiplicity)
264 {
265 throw OrthancException(ErrorCode_ParameterOutOfRange);
266 }
267
268 std::auto_ptr<DcmDictEntry> entry(new DcmDictEntry(tag.GetGroup(),
269 tag.GetElement(),
270 vr, name.c_str(),
271 static_cast<int>(minMultiplicity),
272 static_cast<int>(maxMultiplicity),
273 NULL /* version */,
274 OFTrue /* doCopyString */,
275 NULL /* private creator */));
276
277 entry->setGroupRangeRestriction(DcmDictRange_Unspecified);
278 entry->setElementRangeRestriction(DcmDictRange_Unspecified);
279
280 {
281 DictionaryLocker locker;
282 locker->addEntry(entry.release());
213 } 283 }
214 } 284 }
215 285
216 286
217 Encoding FromDcmtkBridge::DetectEncoding(DcmDataset& dataset) 287 Encoding FromDcmtkBridge::DetectEncoding(DcmDataset& dataset)