Mercurial > hg > orthanc
comparison Core/DicomParsing/DicomModification.cpp @ 2519:2e6b7862ccf2
ParseAnonymizationRequest/ParseModifyRequest now in DicomModification
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 29 Mar 2018 14:52:11 +0200 |
parents | 51b91ead6c38 |
children | b94ed97508e6 |
comparison
equal
deleted
inserted
replaced
2518:63d2cc0fb40a | 2519:2e6b7862ccf2 |
---|---|
1002 { | 1002 { |
1003 visitor.RemoveRelationships(toModify); | 1003 visitor.RemoveRelationships(toModify); |
1004 } | 1004 } |
1005 } | 1005 } |
1006 } | 1006 } |
1007 | |
1008 | |
1009 static bool IsDatabaseKey(const DicomTag& tag) | |
1010 { | |
1011 return (tag == DICOM_TAG_PATIENT_ID || | |
1012 tag == DICOM_TAG_STUDY_INSTANCE_UID || | |
1013 tag == DICOM_TAG_SERIES_INSTANCE_UID || | |
1014 tag == DICOM_TAG_SOP_INSTANCE_UID); | |
1015 } | |
1016 | |
1017 | |
1018 static void ParseListOfTags(DicomModification& target, | |
1019 const Json::Value& query, | |
1020 DicomModification::TagOperation operation, | |
1021 bool force) | |
1022 { | |
1023 if (!query.isArray()) | |
1024 { | |
1025 throw OrthancException(ErrorCode_BadRequest); | |
1026 } | |
1027 | |
1028 for (Json::Value::ArrayIndex i = 0; i < query.size(); i++) | |
1029 { | |
1030 std::string name = query[i].asString(); | |
1031 | |
1032 DicomTag tag = FromDcmtkBridge::ParseTag(name); | |
1033 | |
1034 if (!force && IsDatabaseKey(tag)) | |
1035 { | |
1036 LOG(ERROR) << "Marking tag \"" << name << "\" as to be " | |
1037 << (operation == DicomModification::TagOperation_Keep ? "kept" : "removed") | |
1038 << " requires the \"Force\" option to be set to true"; | |
1039 throw OrthancException(ErrorCode_BadRequest); | |
1040 } | |
1041 | |
1042 switch (operation) | |
1043 { | |
1044 case DicomModification::TagOperation_Keep: | |
1045 target.Keep(tag); | |
1046 VLOG(1) << "Keep: " << name << " " << tag << std::endl; | |
1047 break; | |
1048 | |
1049 case DicomModification::TagOperation_Remove: | |
1050 target.Remove(tag); | |
1051 VLOG(1) << "Remove: " << name << " " << tag << std::endl; | |
1052 break; | |
1053 | |
1054 default: | |
1055 throw OrthancException(ErrorCode_InternalError); | |
1056 } | |
1057 } | |
1058 } | |
1059 | |
1060 | |
1061 static void ParseReplacements(DicomModification& target, | |
1062 const Json::Value& replacements, | |
1063 bool force) | |
1064 { | |
1065 if (!replacements.isObject()) | |
1066 { | |
1067 throw OrthancException(ErrorCode_BadRequest); | |
1068 } | |
1069 | |
1070 Json::Value::Members members = replacements.getMemberNames(); | |
1071 for (size_t i = 0; i < members.size(); i++) | |
1072 { | |
1073 const std::string& name = members[i]; | |
1074 const Json::Value& value = replacements[name]; | |
1075 | |
1076 DicomTag tag = FromDcmtkBridge::ParseTag(name); | |
1077 | |
1078 if (!force && IsDatabaseKey(tag)) | |
1079 { | |
1080 LOG(ERROR) << "Marking tag \"" << name << "\" as to be replaced " | |
1081 << "requires the \"Force\" option to be set to true"; | |
1082 throw OrthancException(ErrorCode_BadRequest); | |
1083 } | |
1084 | |
1085 target.Replace(tag, value, false); | |
1086 | |
1087 VLOG(1) << "Replace: " << name << " " << tag | |
1088 << " == " << value.toStyledString() << std::endl; | |
1089 } | |
1090 } | |
1091 | |
1092 | |
1093 static bool GetBooleanValue(const std::string& member, | |
1094 const Json::Value& json, | |
1095 bool defaultValue) | |
1096 { | |
1097 if (!json.isMember(member)) | |
1098 { | |
1099 return defaultValue; | |
1100 } | |
1101 else if (json[member].type() == Json::booleanValue) | |
1102 { | |
1103 return json[member].asBool(); | |
1104 } | |
1105 else | |
1106 { | |
1107 LOG(ERROR) << "Member \"" << member << "\" should be a Boolean value"; | |
1108 throw OrthancException(ErrorCode_BadFileFormat); | |
1109 } | |
1110 } | |
1111 | |
1112 | |
1113 void DicomModification::ParseModifyRequest(const Json::Value& request) | |
1114 { | |
1115 if (!request.isObject()) | |
1116 { | |
1117 throw OrthancException(ErrorCode_BadFileFormat); | |
1118 } | |
1119 | |
1120 bool force = GetBooleanValue("Force", request, false); | |
1121 | |
1122 if (GetBooleanValue("RemovePrivateTags", request, false)) | |
1123 { | |
1124 SetRemovePrivateTags(true); | |
1125 } | |
1126 | |
1127 if (request.isMember("Remove")) | |
1128 { | |
1129 ParseListOfTags(*this, request["Remove"], TagOperation_Remove, force); | |
1130 } | |
1131 | |
1132 if (request.isMember("Replace")) | |
1133 { | |
1134 ParseReplacements(*this, request["Replace"], force); | |
1135 } | |
1136 | |
1137 // The "Keep" operation only makes sense for the tags | |
1138 // StudyInstanceUID, SeriesInstanceUID and SOPInstanceUID. Avoid | |
1139 // this feature as much as possible, as this breaks the DICOM | |
1140 // model of the real world, except if you know exactly what | |
1141 // you're doing! | |
1142 if (request.isMember("Keep")) | |
1143 { | |
1144 ParseListOfTags(*this, request["Keep"], TagOperation_Keep, force); | |
1145 } | |
1146 } | |
1147 | |
1148 | |
1149 void DicomModification::ParseAnonymizationRequest(bool& patientNameReplaced, | |
1150 const Json::Value& request) | |
1151 { | |
1152 if (!request.isObject()) | |
1153 { | |
1154 throw OrthancException(ErrorCode_BadFileFormat); | |
1155 } | |
1156 | |
1157 bool force = GetBooleanValue("Force", request, false); | |
1158 | |
1159 // As of Orthanc 1.3.0, the default anonymization is done | |
1160 // according to PS 3.15-2017c Table E.1-1 (basic profile) | |
1161 DicomVersion version = DicomVersion_2017c; | |
1162 if (request.isMember("DicomVersion")) | |
1163 { | |
1164 if (request["DicomVersion"].type() != Json::stringValue) | |
1165 { | |
1166 throw OrthancException(ErrorCode_BadFileFormat); | |
1167 } | |
1168 else | |
1169 { | |
1170 version = StringToDicomVersion(request["DicomVersion"].asString()); | |
1171 } | |
1172 } | |
1173 | |
1174 SetupAnonymization(version); | |
1175 | |
1176 std::string patientName = GetReplacementAsString(DICOM_TAG_PATIENT_NAME); | |
1177 | |
1178 if (GetBooleanValue("KeepPrivateTags", request, false)) | |
1179 { | |
1180 SetRemovePrivateTags(false); | |
1181 } | |
1182 | |
1183 if (request.isMember("Remove")) | |
1184 { | |
1185 ParseListOfTags(*this, request["Remove"], TagOperation_Remove, force); | |
1186 } | |
1187 | |
1188 if (request.isMember("Replace")) | |
1189 { | |
1190 ParseReplacements(*this, request["Replace"], force); | |
1191 } | |
1192 | |
1193 if (request.isMember("Keep")) | |
1194 { | |
1195 ParseListOfTags(*this, request["Keep"], TagOperation_Keep, force); | |
1196 } | |
1197 | |
1198 patientNameReplaced = (IsReplaced(DICOM_TAG_PATIENT_NAME) && | |
1199 GetReplacement(DICOM_TAG_PATIENT_NAME) == patientName); | |
1200 } | |
1007 } | 1201 } |