Mercurial > hg > orthanc
changeset 6185:fc0be0031fe8 attach-custom-data
integration mainline->attach-custom-data
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 12 Jun 2025 13:12:37 +0200 |
parents | 7f985407c885 (current diff) d0d08c3833d1 (diff) |
children | b2b1f2dde05c |
files | OrthancServer/Plugins/Engine/OrthancPlugins.cpp |
diffstat | 3 files changed, 130 insertions(+), 120 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.cpp Thu Jun 12 12:49:04 2025 +0200 +++ b/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.cpp Thu Jun 12 13:12:37 2025 +0200 @@ -58,7 +58,6 @@ #include <dcmtk/dcmdata/dcdeftag.h> #include <dcmtk/dcmdata/dcdicent.h> -#include <dcmtk/dcmdata/dcdict.h> #include <dcmtk/dcmdata/dcfilefo.h> #include <dcmtk/dcmdata/dcistrmb.h> #include <dcmtk/dcmdata/dcostrmb.h> @@ -127,6 +126,38 @@ namespace Orthanc { + FromDcmtkBridge::DictionaryWriterLock::DictionaryWriterLock() : + dictionary_(dcmDataDict.wrlock()) + { + } + + + FromDcmtkBridge::DictionaryWriterLock::~DictionaryWriterLock() + { +#if DCMTK_VERSION_NUMBER >= 364 + dcmDataDict.wrunlock(); +#else + dcmDataDict.unlock(); +#endif + } + + + FromDcmtkBridge::DictionaryReaderLock::DictionaryReaderLock() : + dictionary_(dcmDataDict.rdlock()) + { + } + + + FromDcmtkBridge::DictionaryReaderLock::~DictionaryReaderLock() + { +#if DCMTK_VERSION_NUMBER >= 364 + dcmDataDict.rdunlock(); +#else + dcmDataDict.unlock(); +#endif + } + + static bool IsBinaryTag(const DcmTag& key) { return (key.isUnknownVR() || @@ -235,37 +266,6 @@ namespace { - class DictionaryLocker : public boost::noncopyable - { - private: - DcmDataDictionary& dictionary_; - - public: - DictionaryLocker() : dictionary_(dcmDataDict.wrlock()) - { - } - - ~DictionaryLocker() - { -#if DCMTK_VERSION_NUMBER >= 364 - dcmDataDict.wrunlock(); -#else - dcmDataDict.unlock(); -#endif - } - - DcmDataDictionary& operator*() - { - return dictionary_; - } - - DcmDataDictionary* operator->() - { - return &dictionary_; - } - }; - - ORTHANC_FORCE_INLINE static std::string FloatToString(float v) { @@ -364,9 +364,9 @@ #if DCMTK_USE_EMBEDDED_DICTIONARIES == 1 { - DictionaryLocker locker; - - locker->clear(); + DictionaryWriterLock lock; + + lock.GetDictionary().clear(); CLOG(INFO, DICOM) << "Loading the embedded dictionaries"; /** @@ -374,14 +374,14 @@ * command "strace storescu 2>&1 |grep dic" shows that DICONDE * dictionary is not loaded by storescu. **/ - //LoadEmbeddedDictionary(*locker, FrameworkResources::DICTIONARY_DICONDE); - - LoadEmbeddedDictionary(*locker, FrameworkResources::DICTIONARY_DICOM); + //LoadEmbeddedDictionary(*lock, FrameworkResources::DICTIONARY_DICONDE); + + LoadEmbeddedDictionary(*lock, FrameworkResources::DICTIONARY_DICOM); if (loadPrivateDictionary) { CLOG(INFO, DICOM) << "Loading the embedded dictionary of private tags"; - LoadEmbeddedDictionary(*locker, FrameworkResources::DICTIONARY_PRIVATE); + LoadEmbeddedDictionary(*lock, FrameworkResources::DICTIONARY_PRIVATE); } else { @@ -441,16 +441,16 @@ void FromDcmtkBridge::LoadExternalDictionaries(const std::vector<std::string>& dictionaries) { - DictionaryLocker locker; + DictionaryWriterLock lock; CLOG(INFO, DICOM) << "Clearing the DICOM dictionary"; - locker->clear(); + lock.GetDictionary().clear(); for (size_t i = 0; i < dictionaries.size(); i++) { LOG(WARNING) << "Loading external DICOM dictionary: \"" << dictionaries[i] << "\""; - if (!locker->loadDictionary(dictionaries[i].c_str())) + if (!lock.GetDictionary().loadDictionary(dictionaries[i].c_str())) { throw OrthancException(ErrorCode_InexistentFile); } @@ -543,10 +543,10 @@ entry->setElementRangeRestriction(DcmDictRange_Unspecified); { - DictionaryLocker locker; - - if (locker->findEntry(DcmTagKey(tag.GetGroup(), tag.GetElement()), - privateCreator.empty() ? NULL : privateCreator.c_str())) + DictionaryWriterLock lock; + + if (lock.GetDictionary().findEntry(DcmTagKey(tag.GetGroup(), tag.GetElement()), + privateCreator.empty() ? NULL : privateCreator.c_str())) { throw OrthancException(ErrorCode_AlreadyExistingTag, "Cannot register twice the tag (" + tag.Format() + @@ -554,7 +554,7 @@ } else { - locker->addEntry(entry.release()); + lock.GetDictionary().addEntry(entry.release()); } } } @@ -731,10 +731,11 @@ * syntax (cf. DICOM CP 246). * ftp://medical.nema.org/medical/dicom/final/cp246_ft.pdf **/ - DictionaryLocker locker; - - const DcmDictEntry* entry = locker->findEntry(element.getTag().getXTag(), - element.getTag().getPrivateCreator()); + DictionaryReaderLock lock; + + // The "entry" value is only valid while "lock" is active + const DcmDictEntry* entry = lock.GetDictionary().findEntry(element.getTag().getXTag(), + element.getTag().getPrivateCreator()); if (entry != NULL && entry->getVR().isaString()) { @@ -1179,8 +1180,8 @@ if (!(flags & DicomToJsonFlags_IncludeUnknownTags)) { - DictionaryLocker locker; - if (locker->findEntry(element->getTag(), element->getTag().getPrivateCreator()) == NULL) + DictionaryReaderLock lock; + if (lock.GetDictionary().findEntry(element->getTag(), element->getTag().getPrivateCreator()) == NULL) { continue; } @@ -2759,10 +2760,11 @@ if (evr == EVR_UN) { // New in Orthanc 1.9.5 - DictionaryLocker locker; - - const DcmDictEntry* entry = locker->findEntry(element.getTag().getXTag(), - element.getTag().getPrivateCreator()); + FromDcmtkBridge::DictionaryReaderLock lock; + + // The "entry" value is only valid while "lock" is active + const DcmDictEntry* entry = lock.GetDictionary().findEntry(element.getTag().getXTag(), + element.getTag().getPrivateCreator()); if (entry != NULL) {
--- a/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h Thu Jun 12 12:49:04 2025 +0200 +++ b/OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h Thu Jun 12 13:12:37 2025 +0200 @@ -30,9 +30,10 @@ #include "../DicomFormat/DicomPath.h" #include <dcmtk/dcmdata/dcdatset.h> +#include <dcmtk/dcmdata/dcdict.h> +#include <dcmtk/dcmdata/dcfilefo.h> #include <dcmtk/dcmdata/dcmetinf.h> #include <dcmtk/dcmdata/dcpixseq.h> -#include <dcmtk/dcmdata/dcfilefo.h> #include <json/value.h> #if ORTHANC_ENABLE_DCMTK != 1 @@ -86,6 +87,40 @@ }; + class ORTHANC_PUBLIC DictionaryWriterLock : public boost::noncopyable + { + private: + DcmDataDictionary& dictionary_; + + public: + DictionaryWriterLock(); + + ~DictionaryWriterLock(); + + DcmDataDictionary& GetDictionary() + { + return dictionary_; + } + }; + + + class ORTHANC_PUBLIC DictionaryReaderLock : public boost::noncopyable + { + private: + const DcmDataDictionary& dictionary_; + + public: + DictionaryReaderLock(); + + ~DictionaryReaderLock(); + + const DcmDataDictionary& GetDictionary() const + { + return dictionary_; + } + }; + + private: FromDcmtkBridge(); // Pure static class
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Thu Jun 12 12:49:04 2025 +0200 +++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Thu Jun 12 13:12:37 2025 +0200 @@ -70,7 +70,6 @@ #include <boost/math/special_functions/round.hpp> #include <boost/regex.hpp> -#include <dcmtk/dcmdata/dcdict.h> #include <dcmtk/dcmdata/dcdicent.h> #include <dcmtk/dcmnet/dimse.h> @@ -4850,35 +4849,6 @@ } - namespace - { - class DictionaryReadLocker - { - private: - const DcmDataDictionary& dictionary_; - - public: - DictionaryReadLocker() : dictionary_(dcmDataDict.rdlock()) - { - } - - ~DictionaryReadLocker() - { -#if DCMTK_VERSION_NUMBER >= 364 - dcmDataDict.rdunlock(); -#else - dcmDataDict.unlock(); -#endif - } - - const DcmDataDictionary* operator->() - { - return &dictionary_; - } - }; - } - - void OrthancPlugins::ApplyLookupDictionary(const void* parameters) { const _OrthancPluginLookupDictionary& p = @@ -4887,38 +4857,41 @@ DicomTag tag(FromDcmtkBridge::ParseTag(p.name)); DcmTagKey tag2(tag.GetGroup(), tag.GetElement()); - DictionaryReadLocker locker; - const DcmDictEntry* entry = NULL; - - if (tag.IsPrivate()) - { - // Fix issue 168 (Plugins can't read private tags from the - // configuration file) - // https://orthanc.uclouvain.be/bugs/show_bug.cgi?id=168 - std::string privateCreator; - { - OrthancConfiguration::ReaderLock lock; - privateCreator = lock.GetConfiguration().GetDefaultPrivateCreator(); - } - - entry = locker->findEntry(tag2, privateCreator.c_str()); - } - else - { - entry = locker->findEntry(tag2, NULL); - } - - if (entry == NULL) - { - throw OrthancException(ErrorCode_UnknownDicomTag, p.name); - } - else - { - p.target->group = entry->getKey().getGroup(); - p.target->element = entry->getKey().getElement(); - p.target->vr = Plugins::Convert(FromDcmtkBridge::Convert(entry->getEVR())); - p.target->minMultiplicity = static_cast<uint32_t>(entry->getVMMin()); - p.target->maxMultiplicity = (entry->getVMMax() == DcmVariableVM ? 0 : static_cast<uint32_t>(entry->getVMMax())); + { + FromDcmtkBridge::DictionaryReaderLock lock; + + const DcmDictEntry* entry = NULL; // This value is only valid while "lock" is active + + if (tag.IsPrivate()) + { + // Fix issue 168 (Plugins can't read private tags from the + // configuration file) + // https://orthanc.uclouvain.be/bugs/show_bug.cgi?id=168 + std::string privateCreator; + { + OrthancConfiguration::ReaderLock configurationLock; + privateCreator = configurationLock.GetConfiguration().GetDefaultPrivateCreator(); + } + + entry = lock.GetDictionary().findEntry(tag2, privateCreator.c_str()); + } + else + { + entry = lock.GetDictionary().findEntry(tag2, NULL); + } + + if (entry == NULL) + { + throw OrthancException(ErrorCode_UnknownDicomTag, p.name); + } + else + { + p.target->group = entry->getKey().getGroup(); + p.target->element = entry->getKey().getElement(); + p.target->vr = Plugins::Convert(FromDcmtkBridge::Convert(entry->getEVR())); + p.target->minMultiplicity = static_cast<uint32_t>(entry->getVMMin()); + p.target->maxMultiplicity = (entry->getVMMax() == DcmVariableVM ? 0 : static_cast<uint32_t>(entry->getVMMax())); + } } }