Mercurial > hg > orthanc
changeset 1307:f796207e3df1
Fix replacement and insertion of private DICOM tags
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 11 Feb 2015 10:26:17 +0100 |
parents | 8cd5784a6d80 |
children | f7966e9950e4 d1a430176401 |
files | NEWS OrthancServer/FromDcmtkBridge.cpp OrthancServer/ParsedDicomFile.cpp Resources/Samples/Lua/AutoroutingModification.lua UnitTestsSources/FromDcmtkTests.cpp |
diffstat | 5 files changed, 109 insertions(+), 19 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Tue Feb 10 17:17:25 2015 +0100 +++ b/NEWS Wed Feb 11 10:26:17 2015 +0100 @@ -31,6 +31,7 @@ * Code refactorings * Fix issue 25 (AET with underscore not allowed) +* Fix replacement and insertion of private DICOM tags Version 0.8.5 (2014/11/04)
--- a/OrthancServer/FromDcmtkBridge.cpp Tue Feb 10 17:17:25 2015 +0100 +++ b/OrthancServer/FromDcmtkBridge.cpp Wed Feb 11 10:26:17 2015 +0100 @@ -186,15 +186,27 @@ bool FromDcmtkBridge::IsPrivateTag(DcmTag& tag) { +#if 1 + DcmTagKey tmp(tag.getGTag(), tag.getETag()); + return tmp.isPrivate(); +#else + // Implementation for Orthanc versions <= 0.8.5 return (tag.getPrivateCreator() != NULL || !strcmp("PrivateCreator", tag.getTagName())); // TODO - This may change with future versions of DCMTK +#endif } bool FromDcmtkBridge::IsPrivateTag(const DicomTag& tag) { +#if 1 + DcmTagKey tmp(tag.GetGroup(), tag.GetElement()); + return tmp.isPrivate(); +#else + // Implementation for Orthanc versions <= 0.8.5 DcmTag tmp(tag.GetGroup(), tag.GetElement()); return IsPrivateTag(tmp); +#endif }
--- a/OrthancServer/ParsedDicomFile.cpp Tue Feb 10 17:17:25 2015 +0100 +++ b/OrthancServer/ParsedDicomFile.cpp Wed Feb 11 10:26:17 2015 +0100 @@ -807,13 +807,30 @@ + void ParsedDicomFile::Insert(const DicomTag& tag, const std::string& value) { - std::auto_ptr<DcmElement> element(CreateElementForTag(tag)); - FillElementWithString(*element, tag, value); + OFCondition cond; + + if (FromDcmtkBridge::IsPrivateTag(tag)) + { + // This is a private tag + // http://support.dcmtk.org/redmine/projects/dcmtk/wiki/howto_addprivatedata - if (!pimpl_->file_->getDataset()->insert(element.release(), false, false).good()) + DcmTag key(tag.GetGroup(), tag.GetElement(), EVR_OB); + cond = pimpl_->file_->getDataset()->putAndInsertUint8Array + (key, (const Uint8*) value.c_str(), value.size(), false); + } + else + { + std::auto_ptr<DcmElement> element(CreateElementForTag(tag)); + FillElementWithString(*element, tag, value); + + cond = pimpl_->file_->getDataset()->insert(element.release(), false, false); + } + + if (!cond.good()) { // This field already exists throw OrthancException(ErrorCode_InternalError); @@ -847,7 +864,17 @@ } else { - FillElementWithString(*element, tag, value); + if (FromDcmtkBridge::IsPrivateTag(tag)) + { + if (!element->putUint8Array((const Uint8*) value.c_str(), value.size()).good()) + { + throw OrthancException(ErrorCode_InternalError); + } + } + else + { + FillElementWithString(*element, tag, value); + } } @@ -888,25 +915,53 @@ { DcmTagKey k(tag.GetGroup(), tag.GetElement()); DcmDataset& dataset = *pimpl_->file_->getDataset(); - DcmElement* element = NULL; - if (!dataset.findAndGetElement(k, element).good() || - element == NULL) + + if (FromDcmtkBridge::IsPrivateTag(tag)) { - return false; - } + const Uint8* data = NULL; // This is freed in the destructor of the dataset + long unsigned int count = 0; - std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(*element, pimpl_->encoding_)); + if (dataset.findAndGetUint8Array(k, data, &count).good()) + { + if (count > 0) + { + assert(data != NULL); + value.assign(reinterpret_cast<const char*>(data), count); + } + else + { + value.clear(); + } - if (v.get() == NULL) - { - value = ""; + return true; + } + else + { + return false; + } } else { - value = v->AsString(); + DcmElement* element = NULL; + if (!dataset.findAndGetElement(k, element).good() || + element == NULL) + { + return false; + } + + std::auto_ptr<DicomValue> v(FromDcmtkBridge::ConvertLeafElement(*element, pimpl_->encoding_)); + + if (v.get() == NULL) + { + value = ""; + } + else + { + value = v->AsString(); + } + + return true; } - - return true; }
--- a/Resources/Samples/Lua/AutoroutingModification.lua Tue Feb 10 17:17:25 2015 +0100 +++ b/Resources/Samples/Lua/AutoroutingModification.lua Wed Feb 11 10:26:17 2015 +0100 @@ -7,6 +7,7 @@ -- The tags to be replaced local replace = {} replace['StationName'] = 'My Medical Device' + replace['0031-1020'] = 'Some private tag' -- The tags to be removed local remove = { 'MilitaryRank' }
--- a/UnitTestsSources/FromDcmtkTests.cpp Tue Feb 10 17:17:25 2015 +0100 +++ b/UnitTestsSources/FromDcmtkTests.cpp Wed Feb 11 10:26:17 2015 +0100 @@ -89,14 +89,35 @@ TEST(DicomModification, Anonymization) { + ASSERT_EQ(DICOM_TAG_PATIENT_NAME, FromDcmtkBridge::ParseTag("PatientName")); + const DicomTag privateTag(0x0045, 0x0010); + const DicomTag privateTag2(FromDcmtkBridge::ParseTag("0031-1020")); ASSERT_TRUE(FromDcmtkBridge::IsPrivateTag(privateTag)); + ASSERT_TRUE(FromDcmtkBridge::IsPrivateTag(privateTag2)); + ASSERT_EQ(0x0031, privateTag2.GetGroup()); + ASSERT_EQ(0x1020, privateTag2.GetElement()); + std::string s; ParsedDicomFile o; o.Replace(DICOM_TAG_PATIENT_NAME, "coucou"); - o.Replace(privateTag, "private tag"); + ASSERT_FALSE(o.GetTagValue(s, privateTag)); + o.Insert(privateTag, "private tag"); + ASSERT_TRUE(o.GetTagValue(s, privateTag)); + ASSERT_STREQ("private tag", s.c_str()); - std::string s; + ASSERT_FALSE(o.GetTagValue(s, privateTag2)); + ASSERT_THROW(o.Replace(privateTag2, "hello", DicomReplaceMode_ThrowIfAbsent), OrthancException); + ASSERT_FALSE(o.GetTagValue(s, privateTag2)); + o.Replace(privateTag2, "hello", DicomReplaceMode_IgnoreIfAbsent); + ASSERT_FALSE(o.GetTagValue(s, privateTag2)); + o.Replace(privateTag2, "hello", DicomReplaceMode_InsertIfAbsent); + ASSERT_TRUE(o.GetTagValue(s, privateTag2)); + ASSERT_STREQ("hello", s.c_str()); + o.Replace(privateTag2, "hello world"); + ASSERT_TRUE(o.GetTagValue(s, privateTag2)); + ASSERT_STREQ("hello world", s.c_str()); + ASSERT_TRUE(o.GetTagValue(s, DICOM_TAG_PATIENT_NAME)); ASSERT_FALSE(Toolbox::IsUuid(s)); @@ -109,7 +130,7 @@ ASSERT_TRUE(o.GetTagValue(s, DICOM_TAG_PATIENT_NAME)); ASSERT_TRUE(Toolbox::IsUuid(s)); ASSERT_TRUE(o.GetTagValue(s, privateTag)); - ASSERT_EQ("private tag", s); + ASSERT_STREQ("private tag", s.c_str()); m.SetupAnonymization(); m.Apply(o);