# HG changeset patch # User Sebastien Jodogne # Date 1444386561 -7200 # Node ID d78b87f93bcf79ff70337e07dd0ebf03b3241b73 # Parent 21902c8ba95b242d4fbf89a06e982ce0a65f21ce DicomModification use Json::Value diff -r 21902c8ba95b -r d78b87f93bcf OrthancServer/DicomModification.cpp --- a/OrthancServer/DicomModification.cpp Thu Oct 08 14:52:03 2015 +0200 +++ b/OrthancServer/DicomModification.cpp Fri Oct 09 12:29:21 2015 +0200 @@ -44,13 +44,56 @@ namespace Orthanc { + void DicomModification::RemoveInternal(const DicomTag& tag) + { + Replacements::iterator it = replacements_.find(tag); + + if (it != replacements_.end()) + { + delete it->second; + replacements_.erase(it); + } + } + + + void DicomModification::ReplaceInternal(const DicomTag& tag, + const Json::Value& value) + { + Replacements::iterator it = replacements_.find(tag); + + if (it != replacements_.end()) + { + delete it->second; + it->second = NULL; // In the case of an exception during the clone + it->second = new Json::Value(value); // Clone + } + else + { + replacements_[tag] = new Json::Value(value); // Clone + } + } + + + void DicomModification::ClearReplacements() + { + for (Replacements::iterator it = replacements_.begin(); + it != replacements_.end(); ++it) + { + delete it->second; + } + + replacements_.clear(); + } + + void DicomModification::MarkNotOrthancAnonymization() { Replacements::iterator it = replacements_.find(DICOM_TAG_DEIDENTIFICATION_METHOD); if (it != replacements_.end() && - it->second == ORTHANC_DEIDENTIFICATION_METHOD) + it->second->asString() == ORTHANC_DEIDENTIFICATION_METHOD) { + delete it->second; replacements_.erase(it); } } @@ -100,7 +143,7 @@ dicom.Replace(*tag, mapped); } - + DicomModification::DicomModification() { removePrivateTags_ = false; @@ -108,10 +151,15 @@ allowManualIdentifiers_ = true; } + DicomModification::~DicomModification() + { + ClearReplacements(); + } + void DicomModification::Keep(const DicomTag& tag) { removals_.erase(tag); - replacements_.erase(tag); + RemoveInternal(tag); if (FromDcmtkBridge::IsPrivateTag(tag)) { @@ -124,7 +172,7 @@ void DicomModification::Remove(const DicomTag& tag) { removals_.insert(tag); - replacements_.erase(tag); + RemoveInternal(tag); privateTagsToKeep_.erase(tag); MarkNotOrthancAnonymization(); @@ -136,12 +184,12 @@ } void DicomModification::Replace(const DicomTag& tag, - const std::string& utf8Value, + const Json::Value& value, bool safeForAnonymization) { removals_.erase(tag); privateTagsToKeep_.erase(tag); - replacements_[tag] = utf8Value; + ReplaceInternal(tag, value); if (!safeForAnonymization) { @@ -149,12 +197,13 @@ } } + bool DicomModification::IsReplaced(const DicomTag& tag) const { return replacements_.find(tag) != replacements_.end(); } - const std::string& DicomModification::GetReplacement(const DicomTag& tag) const + const Json::Value& DicomModification::GetReplacement(const DicomTag& tag) const { Replacements::const_iterator it = replacements_.find(tag); @@ -164,10 +213,26 @@ } else { - return it->second; + return *it->second; } } + + std::string DicomModification::GetReplacementAsString(const DicomTag& tag) const + { + const Json::Value& json = GetReplacement(tag); + + if (json.type() != Json::stringValue) + { + throw OrthancException(ErrorCode_BadParameterType); + } + else + { + return json.asString(); + } + } + + void DicomModification::SetRemovePrivateTags(bool removed) { removePrivateTags_ = removed; @@ -192,7 +257,7 @@ void DicomModification::SetupAnonymization() { removals_.clear(); - replacements_.clear(); + ClearReplacements(); removePrivateTags_ = true; level_ = ResourceType_Patient; uidMap_.clear(); @@ -255,15 +320,15 @@ removals_.insert(DicomTag(0x0010, 0x2000)); // Medical Alerts // Set the DeidentificationMethod tag - replacements_.insert(std::make_pair(DICOM_TAG_DEIDENTIFICATION_METHOD, ORTHANC_DEIDENTIFICATION_METHOD)); + ReplaceInternal(DICOM_TAG_DEIDENTIFICATION_METHOD, ORTHANC_DEIDENTIFICATION_METHOD); // Set the PatientIdentityRemoved tag - replacements_.insert(std::make_pair(DicomTag(0x0012, 0x0062), "YES")); + ReplaceInternal(DicomTag(0x0012, 0x0062), "YES"); // (*) Choose a random patient name and ID std::string patientId = FromDcmtkBridge::GenerateUniqueIdentifier(ResourceType_Patient); - replacements_[DICOM_TAG_PATIENT_ID] = patientId; - replacements_[DICOM_TAG_PATIENT_NAME] = patientId; + ReplaceInternal(DICOM_TAG_PATIENT_ID, patientId); + ReplaceInternal(DICOM_TAG_PATIENT_NAME, patientId); } void DicomModification::Apply(ParsedDicomFile& toModify) @@ -394,7 +459,7 @@ for (Replacements::const_iterator it = replacements_.begin(); it != replacements_.end(); ++it) { - toModify.Replace(it->first, it->second, DicomReplaceMode_InsertIfAbsent); + toModify.Replace(it->first, *it->second, DicomReplaceMode_InsertIfAbsent); } // (4) Update the DICOM identifiers diff -r 21902c8ba95b -r d78b87f93bcf OrthancServer/DicomModification.h --- a/OrthancServer/DicomModification.h Thu Oct 08 14:52:03 2015 +0200 +++ b/OrthancServer/DicomModification.h Fri Oct 09 12:29:21 2015 +0200 @@ -36,7 +36,7 @@ namespace Orthanc { - class DicomModification + class DicomModification : public boost::noncopyable { /** * Process: @@ -47,7 +47,7 @@ private: typedef std::set SetOfTags; - typedef std::map Replacements; + typedef std::map Replacements; typedef std::map< std::pair, std::string> UidMap; SetOfTags removals_; @@ -63,9 +63,18 @@ void MarkNotOrthancAnonymization(); + void ClearReplacements(); + + void RemoveInternal(const DicomTag& tag); + + void ReplaceInternal(const DicomTag& tag, + const Json::Value& value); + public: DicomModification(); + ~DicomModification(); + void Keep(const DicomTag& tag); void Remove(const DicomTag& tag); @@ -73,12 +82,14 @@ bool IsRemoved(const DicomTag& tag) const; void Replace(const DicomTag& tag, - const std::string& utf8Value, + const Json::Value& value, // Encoded using UTF-8 bool safeForAnonymization = false); bool IsReplaced(const DicomTag& tag) const; - const std::string& GetReplacement(const DicomTag& tag) const; + const Json::Value& GetReplacement(const DicomTag& tag) const; + + std::string GetReplacementAsString(const DicomTag& tag) const; void SetRemovePrivateTags(bool removed); diff -r 21902c8ba95b -r d78b87f93bcf OrthancServer/LuaScripting.cpp --- a/OrthancServer/LuaScripting.cpp Thu Oct 08 14:52:03 2015 +0200 +++ b/OrthancServer/LuaScripting.cpp Fri Oct 09 12:29:21 2015 +0200 @@ -270,10 +270,12 @@ if (operation == "modify") { LOG(INFO) << "Lua script to modify resource " << parameters["Resource"].asString(); - DicomModification modification; - OrthancRestApi::ParseModifyRequest(modification, parameters); + std::auto_ptr modification(new DicomModification); + OrthancRestApi::ParseModifyRequest(*modification, parameters); - std::auto_ptr command(new ModifyInstanceCommand(context_, RequestOrigin_Lua, modification)); + std::auto_ptr command + (new ModifyInstanceCommand(context_, RequestOrigin_Lua, modification.release())); + return command.release(); } diff -r 21902c8ba95b -r d78b87f93bcf OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp --- a/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp Thu Oct 08 14:52:03 2015 +0200 +++ b/OrthancServer/OrthancRestApi/OrthancRestAnonymizeModify.cpp Fri Oct 09 12:29:21 2015 +0200 @@ -168,7 +168,7 @@ // curl http://localhost:8042/instances/6e67da51-d119d6ae-c5667437-87b9a8a5-0f07c49f/anonymize -X POST -d '{"Replace":{"PatientName":"hello","0010-0020":"world"},"Keep":["StudyDescription", "SeriesDescription"],"KeepPrivateTags": null,"Remove":["Modality"]}' > Anonymized.dcm target.SetupAnonymization(); - std::string patientName = target.GetReplacement(DICOM_TAG_PATIENT_NAME); + std::string patientName = target.GetReplacementAsString(DICOM_TAG_PATIENT_NAME); Json::Value request; if (call.ParseJsonRequest(request) && request.isObject()) diff -r 21902c8ba95b -r d78b87f93bcf OrthancServer/Scheduler/ModifyInstanceCommand.cpp --- a/OrthancServer/Scheduler/ModifyInstanceCommand.cpp Thu Oct 08 14:52:03 2015 +0200 +++ b/OrthancServer/Scheduler/ModifyInstanceCommand.cpp Fri Oct 09 12:29:21 2015 +0200 @@ -39,28 +39,28 @@ { ModifyInstanceCommand::ModifyInstanceCommand(ServerContext& context, RequestOrigin origin, - const DicomModification& modification) : + DicomModification* modification) : context_(context), origin_(origin), modification_(modification) { - modification_.SetAllowManualIdentifiers(true); + modification_->SetAllowManualIdentifiers(true); - if (modification_.IsReplaced(DICOM_TAG_PATIENT_ID)) + if (modification_->IsReplaced(DICOM_TAG_PATIENT_ID)) { - modification_.SetLevel(ResourceType_Patient); + modification_->SetLevel(ResourceType_Patient); } - else if (modification_.IsReplaced(DICOM_TAG_STUDY_INSTANCE_UID)) + else if (modification_->IsReplaced(DICOM_TAG_STUDY_INSTANCE_UID)) { - modification_.SetLevel(ResourceType_Study); + modification_->SetLevel(ResourceType_Study); } - else if (modification_.IsReplaced(DICOM_TAG_SERIES_INSTANCE_UID)) + else if (modification_->IsReplaced(DICOM_TAG_SERIES_INSTANCE_UID)) { - modification_.SetLevel(ResourceType_Series); + modification_->SetLevel(ResourceType_Series); } else { - modification_.SetLevel(ResourceType_Instance); + modification_->SetLevel(ResourceType_Instance); } if (origin_ != RequestOrigin_Lua) @@ -71,6 +71,15 @@ } + ModifyInstanceCommand::~ModifyInstanceCommand() + { + if (modification_) + { + delete modification_; + } + } + + bool ModifyInstanceCommand::Apply(ListOfStrings& outputs, const ListOfStrings& inputs) { @@ -88,7 +97,7 @@ modified.reset(lock.GetDicom().Clone()); } - modification_.Apply(*modified); + modification_->Apply(*modified); DicomInstanceToStore toStore; assert(origin_ == RequestOrigin_Lua); diff -r 21902c8ba95b -r d78b87f93bcf OrthancServer/Scheduler/ModifyInstanceCommand.h --- a/OrthancServer/Scheduler/ModifyInstanceCommand.h Thu Oct 08 14:52:03 2015 +0200 +++ b/OrthancServer/Scheduler/ModifyInstanceCommand.h Fri Oct 09 12:29:21 2015 +0200 @@ -43,16 +43,18 @@ private: ServerContext& context_; RequestOrigin origin_; - DicomModification modification_; + DicomModification* modification_; public: ModifyInstanceCommand(ServerContext& context, RequestOrigin origin, - const DicomModification& modification); + DicomModification* modification); // takes the ownership + + virtual ~ModifyInstanceCommand(); const DicomModification& GetModification() const { - return modification_; + return *modification_; } virtual bool Apply(ListOfStrings& outputs,