changeset 2310:b7fba68747f6 issue-46-anonymization

DicomModification::Clear()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 12 Jul 2017 14:00:00 +0200
parents 4dc313b9a20a
children 78dcb3ddea9f
files OrthancServer/DicomModification.cpp OrthancServer/DicomModification.h OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp OrthancServer/ParsedDicomFile.cpp OrthancServer/ParsedDicomFile.h
diffstat 5 files changed, 65 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/DicomModification.cpp	Wed Jul 12 13:40:02 2017 +0200
+++ b/OrthancServer/DicomModification.cpp	Wed Jul 12 14:00:00 2017 +0200
@@ -171,6 +171,7 @@
   void DicomModification::Keep(const DicomTag& tag)
   {
     removals_.erase(tag);
+    clearings_.erase(tag);
     RemoveInternal(tag);
 
     if (tag.IsPrivate())
@@ -194,6 +195,17 @@
   void DicomModification::Remove(const DicomTag& tag)
   {
     removals_.insert(tag);
+    clearings_.erase(tag);
+    RemoveInternal(tag);
+    privateTagsToKeep_.erase(tag);
+
+    MarkNotOrthancAnonymization();
+  }
+
+  void DicomModification::Clear(const DicomTag& tag)
+  {
+    removals_.erase(tag);
+    clearings_.insert(tag);
     RemoveInternal(tag);
     privateTagsToKeep_.erase(tag);
 
@@ -205,10 +217,16 @@
     return removals_.find(tag) != removals_.end();
   }
 
+  bool DicomModification::IsCleared(const DicomTag& tag) const
+  {
+    return clearings_.find(tag) != clearings_.end();
+  }
+
   void DicomModification::Replace(const DicomTag& tag,
                                   const Json::Value& value,
                                   bool safeForAnonymization)
   {
+    clearings_.erase(tag);
     removals_.erase(tag);
     privateTagsToKeep_.erase(tag);
     ReplaceInternal(tag, value);
@@ -606,6 +624,7 @@
   void DicomModification::SetupAnonymization(DicomVersion version)
   {
     removals_.clear();
+    clearings_.clear();
     ClearReplacements();
     removePrivateTags_ = true;
     level_ = ResourceType_Patient;
@@ -756,21 +775,28 @@
       toModify.RemovePrivateTags(privateTagsToKeep_);
     }
 
-    // (2) Remove the tags specified by the user
+    // (2) Clear the tags specified by the user
+    for (SetOfTags::const_iterator it = clearings_.begin(); 
+         it != clearings_.end(); ++it)
+    {
+      toModify.Clear(*it, true /* only clear if the tag exists in the original file */);
+    }
+
+    // (3) Remove the tags specified by the user
     for (SetOfTags::const_iterator it = removals_.begin(); 
          it != removals_.end(); ++it)
     {
       toModify.Remove(*it);
     }
 
-    // (3) Replace the tags
+    // (4) Replace the tags
     for (Replacements::const_iterator it = replacements_.begin(); 
          it != replacements_.end(); ++it)
     {
       toModify.Replace(it->first, *it->second, true /* decode data URI scheme */, DicomReplaceMode_InsertIfAbsent);
     }
 
-    // (4) Update the DICOM identifiers
+    // (5) Update the DICOM identifiers
     if (level_ <= ResourceType_Study &&
         !IsReplaced(DICOM_TAG_STUDY_INSTANCE_UID))
     {
--- a/OrthancServer/DicomModification.h	Wed Jul 12 13:40:02 2017 +0200
+++ b/OrthancServer/DicomModification.h	Wed Jul 12 14:00:00 2017 +0200
@@ -52,6 +52,7 @@
     typedef std::map< std::pair<ResourceType, std::string>, std::string>  UidMap;
 
     SetOfTags removals_;
+    SetOfTags clearings_;
     Replacements replacements_;
     bool removePrivateTags_;
     ResourceType level_;
@@ -88,11 +89,18 @@
 
     void Remove(const DicomTag& tag);
 
+    // Replace the DICOM tag as a NULL/empty value (e.g. for anonymization)
+    void Clear(const DicomTag& tag);
+
     bool IsRemoved(const DicomTag& tag) const;
 
+    bool IsCleared(const DicomTag& tag) const;
+
+    // "safeForAnonymization" tells Orthanc that this replacement does
+    // not break the anonymization process it implements (for internal use only)
     void Replace(const DicomTag& tag,
                  const Json::Value& value,   // Encoded using UTF-8
-                 bool safeForAnonymization = false);
+                 bool safeForAnonymization);
 
     bool IsReplaced(const DicomTag& tag) const;
 
--- a/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp	Wed Jul 12 13:40:02 2017 +0200
+++ b/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp	Wed Jul 12 14:00:00 2017 +0200
@@ -101,7 +101,7 @@
       const Json::Value& value = replacements[name];
 
       DicomTag tag = FromDcmtkBridge::ParseTag(name);
-      target.Replace(tag, value);
+      target.Replace(tag, value, false);
 
       VLOG(1) << "Replace: " << name << " " << tag 
               << " == " << value.toStyledString() << std::endl;
--- a/OrthancServer/ParsedDicomFile.cpp	Wed Jul 12 13:40:02 2017 +0200
+++ b/OrthancServer/ParsedDicomFile.cpp	Wed Jul 12 14:00:00 2017 +0200
@@ -508,6 +508,28 @@
   }
 
 
+  void ParsedDicomFile::Clear(const DicomTag& tag,
+                              bool onlyIfExists)
+  {
+    InvalidateCache();
+
+    DcmItem* dicom = pimpl_->file_->getDataset();
+    DcmTagKey key(tag.GetGroup(), tag.GetElement());
+
+    if (onlyIfExists &&
+        !dicom->tagExists(key))
+    {
+      // The tag is non-existing, do not clear it
+    }
+    else
+    {
+      if (!dicom->insertEmptyElement(key, OFTrue /* replace old value */).good())
+      {
+        throw OrthancException(ErrorCode_InternalError);
+      }
+    }
+  }
+
 
   void ParsedDicomFile::RemovePrivateTagsInternal(const std::set<DicomTag>* toKeep)
   {
--- a/OrthancServer/ParsedDicomFile.h	Wed Jul 12 13:40:02 2017 +0200
+++ b/OrthancServer/ParsedDicomFile.h	Wed Jul 12 14:00:00 2017 +0200
@@ -96,6 +96,10 @@
 
     void Remove(const DicomTag& tag);
 
+    // Replace the DICOM tag as a NULL/empty value (e.g. for anonymization)
+    void Clear(const DicomTag& tag,
+               bool onlyIfExists);
+
     void Replace(const DicomTag& tag,
                  const std::string& utf8Value,
                  bool decodeDataUriScheme,