Mercurial > hg > orthanc
comparison OrthancServer/FromDcmtkBridge.cpp @ 1689:26083d84d237
refactoring
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 07 Oct 2015 16:54:05 +0200 |
parents | 27d70e9ee2e4 |
children | ae09132e4237 |
comparison
equal
deleted
inserted
replaced
1688:27d70e9ee2e4 | 1689:26083d84d237 |
---|---|
93 #include <dcmtk/dcmdata/dcvrat.h> | 93 #include <dcmtk/dcmdata/dcvrat.h> |
94 | 94 |
95 #include <dcmtk/dcmnet/dul.h> | 95 #include <dcmtk/dcmnet/dul.h> |
96 | 96 |
97 #include <boost/math/special_functions/round.hpp> | 97 #include <boost/math/special_functions/round.hpp> |
98 #include <boost/algorithm/string/predicate.hpp> | |
98 #include <dcmtk/dcmdata/dcostrmb.h> | 99 #include <dcmtk/dcmdata/dcostrmb.h> |
99 | 100 |
100 | 101 |
101 namespace Orthanc | 102 namespace Orthanc |
102 { | 103 { |
1021 default: | 1022 default: |
1022 return ValueRepresentation_Other; | 1023 return ValueRepresentation_Other; |
1023 } | 1024 } |
1024 } | 1025 } |
1025 | 1026 |
1027 | |
1028 | |
1029 DcmElement* FromDcmtkBridge::CreateElementForTag(const DicomTag& tag) | |
1030 { | |
1031 DcmTag key(tag.GetGroup(), tag.GetElement()); | |
1032 | |
1033 switch (key.getEVR()) | |
1034 { | |
1035 // http://support.dcmtk.org/docs/dcvr_8h-source.html | |
1036 | |
1037 /** | |
1038 * TODO. | |
1039 **/ | |
1040 | |
1041 case EVR_OB: // other byte | |
1042 case EVR_OF: // other float | |
1043 case EVR_OW: // other word | |
1044 case EVR_AT: // attribute tag | |
1045 throw OrthancException(ErrorCode_NotImplemented); | |
1046 | |
1047 case EVR_UN: // unknown value representation | |
1048 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
1049 | |
1050 | |
1051 /** | |
1052 * String types. | |
1053 * http://support.dcmtk.org/docs/classDcmByteString.html | |
1054 **/ | |
1055 | |
1056 case EVR_AS: // age string | |
1057 return new DcmAgeString(key); | |
1058 | |
1059 case EVR_AE: // application entity title | |
1060 return new DcmApplicationEntity(key); | |
1061 | |
1062 case EVR_CS: // code string | |
1063 return new DcmCodeString(key); | |
1064 | |
1065 case EVR_DA: // date string | |
1066 return new DcmDate(key); | |
1067 | |
1068 case EVR_DT: // date time string | |
1069 return new DcmDateTime(key); | |
1070 | |
1071 case EVR_DS: // decimal string | |
1072 return new DcmDecimalString(key); | |
1073 | |
1074 case EVR_IS: // integer string | |
1075 return new DcmIntegerString(key); | |
1076 | |
1077 case EVR_TM: // time string | |
1078 return new DcmTime(key); | |
1079 | |
1080 case EVR_UI: // unique identifier | |
1081 return new DcmUniqueIdentifier(key); | |
1082 | |
1083 case EVR_ST: // short text | |
1084 return new DcmShortText(key); | |
1085 | |
1086 case EVR_LO: // long string | |
1087 return new DcmLongString(key); | |
1088 | |
1089 case EVR_LT: // long text | |
1090 return new DcmLongText(key); | |
1091 | |
1092 case EVR_UT: // unlimited text | |
1093 return new DcmUnlimitedText(key); | |
1094 | |
1095 case EVR_SH: // short string | |
1096 return new DcmShortString(key); | |
1097 | |
1098 case EVR_PN: // person name | |
1099 return new DcmPersonName(key); | |
1100 | |
1101 | |
1102 /** | |
1103 * Numerical types | |
1104 **/ | |
1105 | |
1106 case EVR_SL: // signed long | |
1107 return new DcmSignedLong(key); | |
1108 | |
1109 case EVR_SS: // signed short | |
1110 return new DcmSignedShort(key); | |
1111 | |
1112 case EVR_UL: // unsigned long | |
1113 return new DcmUnsignedLong(key); | |
1114 | |
1115 case EVR_US: // unsigned short | |
1116 return new DcmUnsignedShort(key); | |
1117 | |
1118 case EVR_FL: // float single-precision | |
1119 return new DcmFloatingPointSingle(key); | |
1120 | |
1121 case EVR_FD: // float double-precision | |
1122 return new DcmFloatingPointDouble(key); | |
1123 | |
1124 | |
1125 /** | |
1126 * Sequence types, should never occur at this point. | |
1127 **/ | |
1128 | |
1129 case EVR_SQ: // sequence of items | |
1130 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
1131 | |
1132 | |
1133 /** | |
1134 * Internal to DCMTK. | |
1135 **/ | |
1136 | |
1137 case EVR_ox: // OB or OW depending on context | |
1138 case EVR_xs: // SS or US depending on context | |
1139 case EVR_lt: // US, SS or OW depending on context, used for LUT Data (thus the name) | |
1140 case EVR_na: // na="not applicable", for data which has no VR | |
1141 case EVR_up: // up="unsigned pointer", used internally for DICOMDIR suppor | |
1142 case EVR_item: // used internally for items | |
1143 case EVR_metainfo: // used internally for meta info datasets | |
1144 case EVR_dataset: // used internally for datasets | |
1145 case EVR_fileFormat: // used internally for DICOM files | |
1146 case EVR_dicomDir: // used internally for DICOMDIR objects | |
1147 case EVR_dirRecord: // used internally for DICOMDIR records | |
1148 case EVR_pixelSQ: // used internally for pixel sequences in a compressed image | |
1149 case EVR_pixelItem: // used internally for pixel items in a compressed image | |
1150 case EVR_UNKNOWN: // used internally for elements with unknown VR (encoded with 4-byte length field in explicit VR) | |
1151 case EVR_PixelData: // used internally for uncompressed pixeld data | |
1152 case EVR_OverlayData: // used internally for overlay data | |
1153 case EVR_UNKNOWN2B: // used internally for elements with unknown VR with 2-byte length field in explicit VR | |
1154 default: | |
1155 break; | |
1156 } | |
1157 | |
1158 throw OrthancException(ErrorCode_InternalError); | |
1159 } | |
1160 | |
1161 | |
1162 | |
1163 void FromDcmtkBridge::FillElementWithString(DcmElement& element, | |
1164 const DicomTag& tag, | |
1165 const std::string& value, | |
1166 bool decodeBinaryTags) | |
1167 { | |
1168 std::string binary; | |
1169 const std::string* decoded = &value; | |
1170 | |
1171 if (decodeBinaryTags && | |
1172 boost::starts_with(value, "data:application/octet-stream;base64,")) | |
1173 { | |
1174 std::string mime; | |
1175 Toolbox::DecodeDataUriScheme(mime, binary, value); | |
1176 decoded = &binary; | |
1177 } | |
1178 | |
1179 | |
1180 if (FromDcmtkBridge::IsPrivateTag(tag) || | |
1181 FromDcmtkBridge::IsUnknownTag(tag)) | |
1182 { | |
1183 if (element.putUint8Array((const Uint8*) decoded->c_str(), decoded->size()).good()) | |
1184 { | |
1185 return; | |
1186 } | |
1187 else | |
1188 { | |
1189 throw OrthancException(ErrorCode_InternalError); | |
1190 } | |
1191 } | |
1192 | |
1193 DcmTag key(tag.GetGroup(), tag.GetElement()); | |
1194 bool ok = false; | |
1195 | |
1196 try | |
1197 { | |
1198 switch (key.getEVR()) | |
1199 { | |
1200 // http://support.dcmtk.org/docs/dcvr_8h-source.html | |
1201 | |
1202 /** | |
1203 * TODO. | |
1204 **/ | |
1205 | |
1206 case EVR_OB: // other byte | |
1207 case EVR_OF: // other float | |
1208 case EVR_OW: // other word | |
1209 case EVR_AT: // attribute tag | |
1210 throw OrthancException(ErrorCode_NotImplemented); | |
1211 | |
1212 case EVR_UN: // unknown value representation | |
1213 throw OrthancException(ErrorCode_ParameterOutOfRange); | |
1214 | |
1215 | |
1216 /** | |
1217 * String types. | |
1218 **/ | |
1219 | |
1220 case EVR_DS: // decimal string | |
1221 case EVR_IS: // integer string | |
1222 case EVR_AS: // age string | |
1223 case EVR_DA: // date string | |
1224 case EVR_DT: // date time string | |
1225 case EVR_TM: // time string | |
1226 case EVR_AE: // application entity title | |
1227 case EVR_CS: // code string | |
1228 case EVR_SH: // short string | |
1229 case EVR_LO: // long string | |
1230 case EVR_ST: // short text | |
1231 case EVR_LT: // long text | |
1232 case EVR_UT: // unlimited text | |
1233 case EVR_PN: // person name | |
1234 case EVR_UI: // unique identifier | |
1235 { | |
1236 ok = element.putString(decoded->c_str()).good(); | |
1237 break; | |
1238 } | |
1239 | |
1240 | |
1241 /** | |
1242 * Numerical types | |
1243 **/ | |
1244 | |
1245 case EVR_SL: // signed long | |
1246 { | |
1247 ok = element.putSint32(boost::lexical_cast<Sint32>(*decoded)).good(); | |
1248 break; | |
1249 } | |
1250 | |
1251 case EVR_SS: // signed short | |
1252 { | |
1253 ok = element.putSint16(boost::lexical_cast<Sint16>(*decoded)).good(); | |
1254 break; | |
1255 } | |
1256 | |
1257 case EVR_UL: // unsigned long | |
1258 { | |
1259 ok = element.putUint32(boost::lexical_cast<Uint32>(*decoded)).good(); | |
1260 break; | |
1261 } | |
1262 | |
1263 case EVR_US: // unsigned short | |
1264 { | |
1265 ok = element.putUint16(boost::lexical_cast<Uint16>(*decoded)).good(); | |
1266 break; | |
1267 } | |
1268 | |
1269 case EVR_FL: // float single-precision | |
1270 { | |
1271 ok = element.putFloat32(boost::lexical_cast<float>(*decoded)).good(); | |
1272 break; | |
1273 } | |
1274 | |
1275 case EVR_FD: // float double-precision | |
1276 { | |
1277 ok = element.putFloat64(boost::lexical_cast<double>(*decoded)).good(); | |
1278 break; | |
1279 } | |
1280 | |
1281 | |
1282 /** | |
1283 * Sequence types, should never occur at this point. | |
1284 **/ | |
1285 | |
1286 case EVR_SQ: // sequence of items | |
1287 { | |
1288 ok = false; | |
1289 break; | |
1290 } | |
1291 | |
1292 | |
1293 /** | |
1294 * Internal to DCMTK. | |
1295 **/ | |
1296 | |
1297 case EVR_ox: // OB or OW depending on context | |
1298 case EVR_xs: // SS or US depending on context | |
1299 case EVR_lt: // US, SS or OW depending on context, used for LUT Data (thus the name) | |
1300 case EVR_na: // na="not applicable", for data which has no VR | |
1301 case EVR_up: // up="unsigned pointer", used internally for DICOMDIR suppor | |
1302 case EVR_item: // used internally for items | |
1303 case EVR_metainfo: // used internally for meta info datasets | |
1304 case EVR_dataset: // used internally for datasets | |
1305 case EVR_fileFormat: // used internally for DICOM files | |
1306 case EVR_dicomDir: // used internally for DICOMDIR objects | |
1307 case EVR_dirRecord: // used internally for DICOMDIR records | |
1308 case EVR_pixelSQ: // used internally for pixel sequences in a compressed image | |
1309 case EVR_pixelItem: // used internally for pixel items in a compressed image | |
1310 case EVR_UNKNOWN: // used internally for elements with unknown VR (encoded with 4-byte length field in explicit VR) | |
1311 case EVR_PixelData: // used internally for uncompressed pixeld data | |
1312 case EVR_OverlayData: // used internally for overlay data | |
1313 case EVR_UNKNOWN2B: // used internally for elements with unknown VR with 2-byte length field in explicit VR | |
1314 default: | |
1315 break; | |
1316 } | |
1317 } | |
1318 catch (boost::bad_lexical_cast&) | |
1319 { | |
1320 ok = false; | |
1321 } | |
1322 | |
1323 if (!ok) | |
1324 { | |
1325 throw OrthancException(ErrorCode_InternalError); | |
1326 } | |
1327 } | |
1328 | |
1329 | |
1330 DcmElement* FromDcmtkBridge::FromJson(const Json::Value& value, | |
1331 const DicomTag& tag, | |
1332 bool decodeBinaryTags) | |
1333 { | |
1334 std::auto_ptr<DcmElement> element; | |
1335 | |
1336 if (value.type() == Json::stringValue) | |
1337 { | |
1338 element.reset(CreateElementForTag(tag)); | |
1339 FillElementWithString(*element, tag, value.asString(), decodeBinaryTags); | |
1340 } | |
1341 | |
1342 return element.release(); | |
1343 } | |
1026 } | 1344 } |