Mercurial > hg > orthanc
comparison OrthancServer/FromDcmtkBridge.cpp @ 1818:1065401501fb worklists
ParsedDicomFile::CreateFromJson
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 24 Nov 2015 16:48:23 +0100 |
parents | b769623c806c |
children | 3ae2ff249675 |
comparison
equal
deleted
inserted
replaced
1817:9a6de24209cf | 1818:1065401501fb |
---|---|
352 { | 352 { |
353 return DicomTag(element.getGTag(), element.getETag()); | 353 return DicomTag(element.getGTag(), element.getETag()); |
354 } | 354 } |
355 | 355 |
356 | 356 |
357 bool FromDcmtkBridge::IsPrivateTag(const DicomTag& tag) | |
358 { | |
359 #if 1 | |
360 DcmTagKey tmp(tag.GetGroup(), tag.GetElement()); | |
361 return tmp.isPrivate(); | |
362 #else | |
363 // Implementation for Orthanc versions <= 0.8.5 | |
364 DcmTag tmp(tag.GetGroup(), tag.GetElement()); | |
365 return IsPrivateTag(tmp); | |
366 #endif | |
367 } | |
368 | |
369 | |
370 DicomValue* FromDcmtkBridge::ConvertLeafElement(DcmElement& element, | 357 DicomValue* FromDcmtkBridge::ConvertLeafElement(DcmElement& element, |
371 DicomToJsonFlags flags, | 358 DicomToJsonFlags flags, |
372 Encoding encoding) | 359 Encoding encoding) |
373 { | 360 { |
374 if (!element.isLeaf()) | 361 if (!element.isLeaf()) |
375 { | 362 { |
376 // This function is only applicable to leaf elements | 363 // This function is only applicable to leaf elements |
377 throw OrthancException(ErrorCode_BadParameterType); | 364 throw OrthancException(ErrorCode_BadParameterType); |
378 } | 365 } |
379 | 366 |
380 if (element.isaString()) | 367 char *c = NULL; |
381 { | 368 if (element.isaString() && |
382 char *c; | 369 element.getString(c).good()) |
383 if (element.getString(c).good()) | 370 { |
384 { | 371 if (c == NULL) // This case corresponds to the empty string |
385 if (c == NULL) // This case corresponds to the empty string | 372 { |
386 { | 373 return new DicomValue("", false); |
387 return new DicomValue("", false); | |
388 } | |
389 else | |
390 { | |
391 std::string s(c); | |
392 std::string utf8 = Toolbox::ConvertToUtf8(s, encoding); | |
393 return new DicomValue(utf8, false); | |
394 } | |
395 } | 374 } |
396 else | 375 else |
397 { | 376 { |
398 return new DicomValue; | 377 std::string s(c); |
378 std::string utf8 = Toolbox::ConvertToUtf8(s, encoding); | |
379 return new DicomValue(utf8, false); | |
399 } | 380 } |
400 } | 381 } |
401 | 382 |
402 try | 383 try |
403 { | 384 { |
412 case EVR_OB: // other byte | 393 case EVR_OB: // other byte |
413 case EVR_OF: // other float | 394 case EVR_OF: // other float |
414 case EVR_OW: // other word | 395 case EVR_OW: // other word |
415 case EVR_UN: // unknown value representation | 396 case EVR_UN: // unknown value representation |
416 case EVR_ox: // OB or OW depending on context | 397 case EVR_ox: // OB or OW depending on context |
417 { | |
418 if (!(flags & DicomToJsonFlags_ConvertBinaryToNull)) | |
419 { | |
420 Uint8* data = NULL; | |
421 if (element.getUint8Array(data) == EC_Normal) | |
422 { | |
423 return new DicomValue(reinterpret_cast<const char*>(data), element.getLength(), true); | |
424 } | |
425 } | |
426 | |
427 return new DicomValue; | |
428 } | |
429 | |
430 /** | |
431 * String types, should never happen at this point because of | |
432 * "element.isaString()". | |
433 **/ | |
434 | |
435 case EVR_DS: // decimal string | 398 case EVR_DS: // decimal string |
436 case EVR_IS: // integer string | 399 case EVR_IS: // integer string |
437 case EVR_AS: // age string | 400 case EVR_AS: // age string |
438 case EVR_DA: // date string | 401 case EVR_DA: // date string |
439 case EVR_DT: // date time string | 402 case EVR_DT: // date time string |
445 case EVR_ST: // short text | 408 case EVR_ST: // short text |
446 case EVR_LT: // long text | 409 case EVR_LT: // long text |
447 case EVR_UT: // unlimited text | 410 case EVR_UT: // unlimited text |
448 case EVR_PN: // person name | 411 case EVR_PN: // person name |
449 case EVR_UI: // unique identifier | 412 case EVR_UI: // unique identifier |
413 case EVR_UNKNOWN: // used internally for elements with unknown VR (encoded with 4-byte length field in explicit VR) | |
414 case EVR_UNKNOWN2B: // used internally for elements with unknown VR with 2-byte length field in explicit VR | |
415 { | |
416 if (!(flags & DicomToJsonFlags_ConvertBinaryToNull)) | |
417 { | |
418 Uint8* data = NULL; | |
419 if (element.getUint8Array(data) == EC_Normal) | |
420 { | |
421 return new DicomValue(reinterpret_cast<const char*>(data), element.getLength(), true); | |
422 } | |
423 } | |
424 | |
450 return new DicomValue; | 425 return new DicomValue; |
451 | 426 } |
452 | 427 |
453 /** | 428 /** |
454 * Numberic types | 429 * Numberic types |
455 **/ | 430 **/ |
456 | 431 |
457 case EVR_SL: // signed long | 432 case EVR_SL: // signed long |
458 { | 433 { |
459 Sint32 f; | 434 Sint32 f; |
460 if (dynamic_cast<DcmSignedLong&>(element).getSint32(f).good()) | 435 if (dynamic_cast<DcmSignedLong&>(element).getSint32(f).good()) |
551 case EVR_fileFormat: // used internally for DICOM files | 526 case EVR_fileFormat: // used internally for DICOM files |
552 case EVR_dicomDir: // used internally for DICOMDIR objects | 527 case EVR_dicomDir: // used internally for DICOMDIR objects |
553 case EVR_dirRecord: // used internally for DICOMDIR records | 528 case EVR_dirRecord: // used internally for DICOMDIR records |
554 case EVR_pixelSQ: // used internally for pixel sequences in a compressed image | 529 case EVR_pixelSQ: // used internally for pixel sequences in a compressed image |
555 case EVR_pixelItem: // used internally for pixel items in a compressed image | 530 case EVR_pixelItem: // used internally for pixel items in a compressed image |
556 case EVR_UNKNOWN: // used internally for elements with unknown VR (encoded with 4-byte length field in explicit VR) | |
557 case EVR_PixelData: // used internally for uncompressed pixeld data | 531 case EVR_PixelData: // used internally for uncompressed pixeld data |
558 case EVR_OverlayData: // used internally for overlay data | 532 case EVR_OverlayData: // used internally for overlay data |
559 case EVR_UNKNOWN2B: // used internally for elements with unknown VR with 2-byte length field in explicit VR | |
560 return new DicomValue; | 533 return new DicomValue; |
561 | 534 |
562 | 535 |
563 /** | 536 /** |
564 * Default case. | 537 * Default case. |
780 if (element == NULL) | 753 if (element == NULL) |
781 { | 754 { |
782 throw OrthancException(ErrorCode_InternalError); | 755 throw OrthancException(ErrorCode_InternalError); |
783 } | 756 } |
784 | 757 |
785 if (!(flags & DicomToJsonFlags_IncludePrivateTags) && | 758 DicomTag tag(FromDcmtkBridge::Convert(element->getTag())); |
786 element->getTag().isPrivate()) | 759 |
760 /*element->getTag().isPrivate()*/ | |
761 if (tag.IsPrivate() && | |
762 !(flags & DicomToJsonFlags_IncludePrivateTags)) | |
787 { | 763 { |
788 continue; | 764 continue; |
789 } | 765 } |
790 | 766 |
791 if (!(flags & DicomToJsonFlags_IncludeUnknownTags)) | 767 if (!(flags & DicomToJsonFlags_IncludeUnknownTags)) |
803 evr == EVR_OW || | 779 evr == EVR_OW || |
804 evr == EVR_UN || | 780 evr == EVR_UN || |
805 evr == EVR_ox) | 781 evr == EVR_ox) |
806 { | 782 { |
807 // This is a binary tag | 783 // This is a binary tag |
808 DicomTag tag(FromDcmtkBridge::Convert(element->getTag())); | |
809 | |
810 if ((tag == DICOM_TAG_PIXEL_DATA && !(flags & DicomToJsonFlags_IncludePixelData)) || | 784 if ((tag == DICOM_TAG_PIXEL_DATA && !(flags & DicomToJsonFlags_IncludePixelData)) || |
811 (tag != DICOM_TAG_PIXEL_DATA && !(flags & DicomToJsonFlags_IncludeBinary))) | 785 (tag != DICOM_TAG_PIXEL_DATA && !(flags & DicomToJsonFlags_IncludeBinary))) |
812 { | 786 { |
813 continue; | 787 continue; |
814 } | 788 } |
1082 } | 1056 } |
1083 | 1057 |
1084 | 1058 |
1085 static bool IsBinaryTag(const DcmTag& key) | 1059 static bool IsBinaryTag(const DcmTag& key) |
1086 { | 1060 { |
1087 return (key.isPrivate() || | 1061 return (key.isUnknownVR() || |
1088 key.isUnknownVR() || | |
1089 key.getEVR() == EVR_OB || | 1062 key.getEVR() == EVR_OB || |
1090 key.getEVR() == EVR_OF || | 1063 key.getEVR() == EVR_OF || |
1091 key.getEVR() == EVR_OW || | 1064 key.getEVR() == EVR_OW || |
1092 key.getEVR() == EVR_UN || | 1065 key.getEVR() == EVR_UN || |
1093 key.getEVR() == EVR_ox); | 1066 key.getEVR() == EVR_ox); |
1096 | 1069 |
1097 DcmElement* FromDcmtkBridge::CreateElementForTag(const DicomTag& tag) | 1070 DcmElement* FromDcmtkBridge::CreateElementForTag(const DicomTag& tag) |
1098 { | 1071 { |
1099 DcmTag key(tag.GetGroup(), tag.GetElement()); | 1072 DcmTag key(tag.GetGroup(), tag.GetElement()); |
1100 | 1073 |
1101 if (IsBinaryTag(key)) | 1074 if (tag.IsPrivate() || |
1075 IsBinaryTag(key)) | |
1102 { | 1076 { |
1103 return new DcmOtherByteOtherWord(key); | 1077 return new DcmOtherByteOtherWord(key); |
1104 } | 1078 } |
1105 | 1079 |
1106 switch (key.getEVR()) | 1080 switch (key.getEVR()) |
1239 | 1213 |
1240 | 1214 |
1241 void FromDcmtkBridge::FillElementWithString(DcmElement& element, | 1215 void FromDcmtkBridge::FillElementWithString(DcmElement& element, |
1242 const DicomTag& tag, | 1216 const DicomTag& tag, |
1243 const std::string& utf8Value, | 1217 const std::string& utf8Value, |
1244 bool decodeBinaryTags, | 1218 bool decodeDataUriScheme, |
1245 Encoding dicomEncoding) | 1219 Encoding dicomEncoding) |
1246 { | 1220 { |
1247 std::string binary; | 1221 std::string binary; |
1248 const std::string* decoded = &utf8Value; | 1222 const std::string* decoded = &utf8Value; |
1249 | 1223 |
1250 if (decodeBinaryTags && | 1224 if (decodeDataUriScheme && |
1251 boost::starts_with(utf8Value, "data:application/octet-stream;base64,")) | 1225 boost::starts_with(utf8Value, "data:application/octet-stream;base64,")) |
1252 { | 1226 { |
1253 std::string mime; | 1227 std::string mime; |
1254 Toolbox::DecodeDataUriScheme(mime, binary, utf8Value); | 1228 Toolbox::DecodeDataUriScheme(mime, binary, utf8Value); |
1255 decoded = &binary; | 1229 decoded = &binary; |
1260 decoded = &binary; | 1234 decoded = &binary; |
1261 } | 1235 } |
1262 | 1236 |
1263 DcmTag key(tag.GetGroup(), tag.GetElement()); | 1237 DcmTag key(tag.GetGroup(), tag.GetElement()); |
1264 | 1238 |
1265 if (IsBinaryTag(key)) | 1239 if (tag.IsPrivate() || |
1240 IsBinaryTag(key)) | |
1266 { | 1241 { |
1267 if (element.putUint8Array((const Uint8*) decoded->c_str(), decoded->size()).good()) | 1242 if (element.putUint8Array((const Uint8*) decoded->c_str(), decoded->size()).good()) |
1268 { | 1243 { |
1269 return; | 1244 return; |
1270 } | 1245 } |
1410 } | 1385 } |
1411 | 1386 |
1412 | 1387 |
1413 DcmElement* FromDcmtkBridge::FromJson(const DicomTag& tag, | 1388 DcmElement* FromDcmtkBridge::FromJson(const DicomTag& tag, |
1414 const Json::Value& value, | 1389 const Json::Value& value, |
1415 bool decodeBinaryTags, | 1390 bool decodeDataUriScheme, |
1416 Encoding dicomEncoding) | 1391 Encoding dicomEncoding) |
1417 { | 1392 { |
1418 std::auto_ptr<DcmElement> element; | 1393 std::auto_ptr<DcmElement> element; |
1419 | 1394 |
1420 switch (value.type()) | 1395 switch (value.type()) |
1421 { | 1396 { |
1422 case Json::stringValue: | 1397 case Json::stringValue: |
1423 element.reset(CreateElementForTag(tag)); | 1398 element.reset(CreateElementForTag(tag)); |
1424 FillElementWithString(*element, tag, value.asString(), decodeBinaryTags, dicomEncoding); | 1399 FillElementWithString(*element, tag, value.asString(), decodeDataUriScheme, dicomEncoding); |
1425 break; | 1400 break; |
1426 | 1401 |
1427 case Json::arrayValue: | 1402 case Json::arrayValue: |
1428 { | 1403 { |
1429 DcmTag key(tag.GetGroup(), tag.GetElement()); | 1404 DcmTag key(tag.GetGroup(), tag.GetElement()); |
1440 std::auto_ptr<DcmItem> item(new DcmItem); | 1415 std::auto_ptr<DcmItem> item(new DcmItem); |
1441 | 1416 |
1442 Json::Value::Members members = value[i].getMemberNames(); | 1417 Json::Value::Members members = value[i].getMemberNames(); |
1443 for (Json::Value::ArrayIndex j = 0; j < members.size(); j++) | 1418 for (Json::Value::ArrayIndex j = 0; j < members.size(); j++) |
1444 { | 1419 { |
1445 item->insert(FromJson(ParseTag(members[j]), value[i][members[j]], decodeBinaryTags, dicomEncoding)); | 1420 item->insert(FromJson(ParseTag(members[j]), value[i][members[j]], decodeDataUriScheme, dicomEncoding)); |
1446 } | 1421 } |
1447 | 1422 |
1448 sequence->append(item.release()); | 1423 sequence->append(item.release()); |
1449 } | 1424 } |
1450 | 1425 |