Mercurial > hg > orthanc
comparison UnitTestsSources/DicomMapTests.cpp @ 3195:880e4161c312
cont
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 05 Feb 2019 20:44:26 +0100 |
parents | 47ef29168698 |
children | 763738c1f9f6 |
comparison
equal
deleted
inserted
replaced
3194:47ef29168698 | 3195:880e4161c312 |
---|---|
557 | 557 |
558 #if 0 | 558 #if 0 |
559 | 559 |
560 #include <boost/math/special_functions/round.hpp> | 560 #include <boost/math/special_functions/round.hpp> |
561 | 561 |
562 | |
563 static const char* const KEY_ALPHABETIC = "Alphabetic"; | |
564 static const char* const KEY_INLINE_BINARY = "InlineBinary"; | |
565 static const char* const KEY_SQ = "SQ"; | |
566 static const char* const KEY_VALUE = "Value"; | |
567 static const char* const KEY_VR = "vr"; | |
568 | |
562 namespace Orthanc | 569 namespace Orthanc |
563 { | 570 { |
564 class DicomJsonVisitor : public ITagVisitor | 571 class DicomJsonVisitor : public ITagVisitor |
565 { | 572 { |
566 private: | 573 private: |
587 std::string t = FormatTag(parentTags[i]); | 594 std::string t = FormatTag(parentTags[i]); |
588 | 595 |
589 if (!node->isMember(t)) | 596 if (!node->isMember(t)) |
590 { | 597 { |
591 Json::Value item = Json::objectValue; | 598 Json::Value item = Json::objectValue; |
592 item["vr"] = "SQ"; | 599 item[KEY_VR] = KEY_SQ; |
593 item["Value"] = Json::arrayValue; | 600 item[KEY_VALUE] = Json::arrayValue; |
594 item["Value"].append(Json::objectValue); | 601 item[KEY_VALUE].append(Json::objectValue); |
595 (*node) [t] = item; | 602 (*node) [t] = item; |
596 | 603 |
597 node = &(*node)[t]["Value"][0]; | 604 node = &(*node)[t][KEY_VALUE][0]; |
598 } | 605 } |
599 else if ((*node) [t].type() != Json::objectValue || | 606 else if ((*node) [t].type() != Json::objectValue || |
600 !(*node) [t].isMember("vr") || | 607 !(*node) [t].isMember(KEY_VR) || |
601 (*node) [t]["vr"].type() != Json::stringValue || | 608 (*node) [t][KEY_VR].type() != Json::stringValue || |
602 (*node) [t]["vr"].asString() != "SQ" || | 609 (*node) [t][KEY_VR].asString() != KEY_SQ || |
603 !(*node) [t].isMember("Value") || | 610 !(*node) [t].isMember(KEY_VALUE) || |
604 (*node) [t]["Value"].type() != Json::arrayValue) | 611 (*node) [t][KEY_VALUE].type() != Json::arrayValue) |
605 { | 612 { |
606 throw OrthancException(ErrorCode_InternalError); | 613 throw OrthancException(ErrorCode_InternalError); |
607 } | 614 } |
608 else | 615 else |
609 { | 616 { |
610 size_t currentSize = (*node) [t]["Value"].size(); | 617 size_t currentSize = (*node) [t][KEY_VALUE].size(); |
611 | 618 |
612 if (parentIndexes[i] < currentSize) | 619 if (parentIndexes[i] < currentSize) |
613 { | 620 { |
614 // The node already exists | 621 // The node already exists |
615 } | 622 } |
616 else if (parentIndexes[i] == currentSize) | 623 else if (parentIndexes[i] == currentSize) |
617 { | 624 { |
618 (*node) [t]["Value"].append(Json::objectValue); | 625 (*node) [t][KEY_VALUE].append(Json::objectValue); |
619 } | 626 } |
620 else | 627 else |
621 { | 628 { |
622 throw OrthancException(ErrorCode_InternalError); | 629 throw OrthancException(ErrorCode_InternalError); |
623 } | 630 } |
624 | 631 |
625 node = &(*node) [t]["Value"][Json::ArrayIndex(parentIndexes[i])]; | 632 node = &(*node) [t][KEY_VALUE][Json::ArrayIndex(parentIndexes[i])]; |
626 } | 633 } |
627 } | 634 } |
628 | 635 |
629 assert(node->type() == Json::objectValue); | 636 assert(node->type() == Json::objectValue); |
630 | 637 |
687 const Json::Value& GetResult() const | 694 const Json::Value& GetResult() const |
688 { | 695 { |
689 return result_; | 696 return result_; |
690 } | 697 } |
691 | 698 |
692 virtual void VisitUnknown(const std::vector<DicomTag>& parentTags, | 699 virtual void VisitNotSupported(const std::vector<DicomTag>& parentTags, |
693 const std::vector<size_t>& parentIndexes, | 700 const std::vector<size_t>& parentIndexes, |
694 const DicomTag& tag, | 701 const DicomTag& tag, |
695 ValueRepresentation vr) ORTHANC_OVERRIDE | 702 ValueRepresentation vr) ORTHANC_OVERRIDE |
696 { | 703 { |
697 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); | 704 } |
698 node["vr"] = EnumerationToString(vr); | 705 |
706 virtual void VisitEmptySequence(const std::vector<DicomTag>& parentTags, | |
707 const std::vector<size_t>& parentIndexes, | |
708 const DicomTag& tag) ORTHANC_OVERRIDE | |
709 { | |
710 if (tag.GetElement() != 0x0000) | |
711 { | |
712 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); | |
713 node[KEY_VR] = EnumerationToString(ValueRepresentation_Sequence); | |
714 } | |
699 } | 715 } |
700 | 716 |
701 virtual void VisitBinary(const std::vector<DicomTag>& parentTags, | 717 virtual void VisitBinary(const std::vector<DicomTag>& parentTags, |
702 const std::vector<size_t>& parentIndexes, | 718 const std::vector<size_t>& parentIndexes, |
703 const DicomTag& tag, | 719 const DicomTag& tag, |
704 ValueRepresentation vr, | 720 ValueRepresentation vr, |
705 const void* data, | 721 const void* data, |
706 size_t size) ORTHANC_OVERRIDE | 722 size_t size) ORTHANC_OVERRIDE |
707 { | 723 { |
708 if (vr != ValueRepresentation_NotSupported && | 724 if (tag.GetElement() != 0x0000 && |
709 !bulkUriRoot_.empty()) | 725 vr != ValueRepresentation_NotSupported /*&& |
726 !bulkUriRoot_.empty()*/) | |
710 { | 727 { |
711 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); | 728 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); |
712 node["vr"] = EnumerationToString(vr); | 729 node[KEY_VR] = EnumerationToString(vr); |
730 | |
731 std::string tmp(static_cast<const char*>(data), size); | |
732 | |
733 std::string base64; | |
734 Toolbox::EncodeBase64(base64, tmp); | |
735 | |
736 node[KEY_INLINE_BINARY] = base64; | |
713 } | 737 } |
714 } | 738 } |
715 | 739 |
716 virtual void VisitIntegers(const std::vector<DicomTag>& parentTags, | 740 virtual void VisitIntegers(const std::vector<DicomTag>& parentTags, |
717 const std::vector<size_t>& parentIndexes, | 741 const std::vector<size_t>& parentIndexes, |
718 const DicomTag& tag, | 742 const DicomTag& tag, |
719 ValueRepresentation vr, | 743 ValueRepresentation vr, |
720 const std::vector<int64_t>& values) ORTHANC_OVERRIDE | 744 const std::vector<int64_t>& values) ORTHANC_OVERRIDE |
721 { | 745 { |
722 if (vr != ValueRepresentation_NotSupported) | 746 if (tag.GetElement() != 0x0000 && |
747 vr != ValueRepresentation_NotSupported) | |
723 { | 748 { |
724 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); | 749 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); |
725 node["vr"] = EnumerationToString(vr); | 750 node[KEY_VR] = EnumerationToString(vr); |
726 | 751 |
727 Json::Value content = Json::arrayValue; | 752 if (!values.empty()) |
728 for (size_t i = 0; i < values.size(); i++) | |
729 { | 753 { |
730 content.append(FormatInteger(values[i])); | 754 Json::Value content = Json::arrayValue; |
755 for (size_t i = 0; i < values.size(); i++) | |
756 { | |
757 content.append(FormatInteger(values[i])); | |
758 } | |
759 | |
760 node[KEY_VALUE] = content; | |
731 } | 761 } |
732 | |
733 node["Value"] = content; | |
734 } | 762 } |
735 } | 763 } |
736 | 764 |
737 virtual void VisitDoubles(const std::vector<DicomTag>& parentTags, | 765 virtual void VisitDoubles(const std::vector<DicomTag>& parentTags, |
738 const std::vector<size_t>& parentIndexes, | 766 const std::vector<size_t>& parentIndexes, |
739 const DicomTag& tag, | 767 const DicomTag& tag, |
740 ValueRepresentation vr, | 768 ValueRepresentation vr, |
741 const std::vector<double>& values) ORTHANC_OVERRIDE | 769 const std::vector<double>& values) ORTHANC_OVERRIDE |
742 { | 770 { |
743 if (vr != ValueRepresentation_NotSupported) | 771 if (tag.GetElement() != 0x0000 && |
772 vr != ValueRepresentation_NotSupported) | |
744 { | 773 { |
745 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); | 774 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); |
746 node["vr"] = EnumerationToString(vr); | 775 node[KEY_VR] = EnumerationToString(vr); |
747 | 776 |
748 Json::Value content = Json::arrayValue; | 777 if (!values.empty()) |
749 for (size_t i = 0; i < values.size(); i++) | |
750 { | 778 { |
751 content.append(FormatDouble(values[i])); | 779 Json::Value content = Json::arrayValue; |
780 for (size_t i = 0; i < values.size(); i++) | |
781 { | |
782 content.append(FormatDouble(values[i])); | |
783 } | |
784 | |
785 node[KEY_VALUE] = content; | |
752 } | 786 } |
753 node["Value"] = content; | |
754 } | 787 } |
755 } | 788 } |
756 | 789 |
757 virtual void VisitAttributes(const std::vector<DicomTag>& parentTags, | 790 virtual void VisitAttributes(const std::vector<DicomTag>& parentTags, |
758 const std::vector<size_t>& parentIndexes, | 791 const std::vector<size_t>& parentIndexes, |
759 const DicomTag& tag, | 792 const DicomTag& tag, |
760 ValueRepresentation vr, | |
761 const std::vector<DicomTag>& values) ORTHANC_OVERRIDE | 793 const std::vector<DicomTag>& values) ORTHANC_OVERRIDE |
762 { | 794 { |
763 if (vr != ValueRepresentation_NotSupported) | 795 if (tag.GetElement() != 0x0000) |
764 { | 796 { |
765 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); | 797 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); |
766 node["vr"] = EnumerationToString(vr); | 798 node[KEY_VR] = EnumerationToString(ValueRepresentation_AttributeTag); |
767 | 799 |
768 | 800 if (!values.empty()) |
801 { | |
802 // TODO | |
803 } | |
769 } | 804 } |
770 } | 805 } |
771 | 806 |
772 virtual Action VisitString(std::string& newValue, | 807 virtual Action VisitString(std::string& newValue, |
773 const std::vector<DicomTag>& parentTags, | 808 const std::vector<DicomTag>& parentTags, |
774 const std::vector<size_t>& parentIndexes, | 809 const std::vector<size_t>& parentIndexes, |
775 const DicomTag& tag, | 810 const DicomTag& tag, |
776 ValueRepresentation vr, | 811 ValueRepresentation vr, |
777 const std::string& value) ORTHANC_OVERRIDE | 812 const std::string& value) ORTHANC_OVERRIDE |
778 { | 813 { |
779 if (vr != ValueRepresentation_NotSupported) | 814 if (tag.GetElement() != 0x0000 && |
815 vr != ValueRepresentation_NotSupported) | |
780 { | 816 { |
781 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); | 817 Json::Value& node = CreateNode(parentTags, parentIndexes, tag); |
782 node["vr"] = EnumerationToString(vr); | 818 node[KEY_VR] = EnumerationToString(vr); |
783 | 819 |
784 std::vector<std::string> tokens; | 820 if (!value.empty()) |
785 Toolbox::TokenizeString(tokens, value, '\\'); | |
786 | |
787 node["Value"] = Json::arrayValue; | |
788 for (size_t i = 0; i < tokens.size(); i++) | |
789 { | 821 { |
790 try | 822 std::vector<std::string> tokens; |
823 Toolbox::TokenizeString(tokens, value, '\\'); | |
824 | |
825 node[KEY_VALUE] = Json::arrayValue; | |
826 for (size_t i = 0; i < tokens.size(); i++) | |
791 { | 827 { |
792 switch (vr) | 828 try |
793 { | 829 { |
794 case ValueRepresentation_PersonName: | 830 switch (vr) |
795 { | 831 { |
796 Json::Value value = Json::objectValue; | 832 case ValueRepresentation_PersonName: |
797 value["Alphabetic"] = tokens[i]; | 833 { |
798 node["Value"].append(value); | 834 Json::Value value = Json::objectValue; |
799 break; | 835 if (!tokens[i].empty()) |
800 } | 836 { |
837 value[KEY_ALPHABETIC] = tokens[i]; | |
838 } | |
839 node[KEY_VALUE].append(value); | |
840 break; | |
841 } | |
801 | 842 |
802 case ValueRepresentation_IntegerString: | 843 case ValueRepresentation_IntegerString: |
803 { | 844 { |
804 int64_t value = boost::lexical_cast<int64_t>(tokens[i]); | 845 int64_t value = boost::lexical_cast<int64_t>(tokens[i]); |
805 node["Value"].append(FormatInteger(value)); | 846 node[KEY_VALUE].append(FormatInteger(value)); |
806 break; | 847 break; |
807 } | 848 } |
808 | 849 |
809 case ValueRepresentation_DecimalString: | 850 case ValueRepresentation_DecimalString: |
810 { | 851 { |
811 double value = boost::lexical_cast<double>(tokens[i]); | 852 double value = boost::lexical_cast<double>(tokens[i]); |
812 node["Value"].append(FormatDouble(value)); | 853 node[KEY_VALUE].append(FormatDouble(value)); |
813 break; | 854 break; |
814 } | 855 } |
815 | 856 |
816 default: | 857 default: |
817 { | |
818 size_t l = tokens[i].size(); | |
819 | |
820 if (l > 0 && | |
821 tokens[i][l - 1] == '\0') | |
822 { | 858 { |
823 tokens[i] = tokens[i].substr(0, l - 1); | 859 size_t l = tokens[i].size(); |
860 | |
861 if (l > 0 && | |
862 tokens[i][l - 1] == '\0') | |
863 { | |
864 tokens[i] = tokens[i].substr(0, l - 1); | |
865 } | |
866 | |
867 node[KEY_VALUE].append(tokens[i]); | |
868 break; | |
824 } | 869 } |
825 | |
826 node["Value"].append(tokens[i]); | |
827 break; | |
828 } | 870 } |
829 } | 871 } |
830 } | 872 catch (boost::bad_lexical_cast&) |
831 catch (boost::bad_lexical_cast&) | 873 { |
832 { | 874 throw OrthancException(ErrorCode_BadFileFormat); |
833 throw OrthancException(ErrorCode_BadFileFormat); | 875 } |
834 } | 876 } |
835 } | 877 } |
836 } | 878 } |
837 | 879 |
838 return Action_None; | 880 return Action_None; |
842 | 884 |
843 #include "../Core/SystemToolbox.h" | 885 #include "../Core/SystemToolbox.h" |
844 | 886 |
845 | 887 |
846 /* | 888 /* |
889 | |
890 MarekLatin2.dcm | |
891 HierarchicalAnonymization/StructuredReports/IM0 | |
892 DummyCT.dcm | |
893 Brainix/Epi/IM-0001-0018.dcm | |
894 | |
847 | 895 |
848 cat << EOF > /tmp/tutu.py | 896 cat << EOF > /tmp/tutu.py |
849 import json | 897 import json |
850 import sys | 898 import sys |
851 j = json.loads(sys.stdin.read().decode("utf-8-sig")) | 899 j = json.loads(sys.stdin.read().decode("utf-8-sig")) |
852 print(json.dumps(j, indent=4, sort_keys=True, ensure_ascii=False).encode('utf-8')) | 900 print(json.dumps(j, indent=4, sort_keys=True, ensure_ascii=False).encode('utf-8')) |
853 EOF | 901 EOF |
854 | 902 |
855 DCMDICTPATH=/home/jodogne/Downloads/dcmtk-3.6.2/dcmdata/data/dicom.dic /home/jodogne/Downloads/dcmtk-3.6.2/i/bin/dcm2json ~/Subversion/orthanc-tests/Database/DummyCT.dcm | tr -d '\0' | sed 's/\\u0000//g' | sed 's/\.0$//' | python /tmp/tutu.py | grep -v 'InlineBinary' > /tmp/a.json | 903 DCMDICTPATH=/home/jodogne/Downloads/dcmtk-3.6.4/dcmdata/data/dicom.dic /home/jodogne/Downloads/dcmtk-3.6.4/i/bin/dcm2json ~/Subversion/orthanc-tests/Database/HierarchicalAnonymization/StructuredReports/IM0 | tr -d '\0' | sed 's/\\u0000//g' | sed 's/\.0$//' | python /tmp/tutu.py > /tmp/a.json |
856 | 904 |
857 make -j4 && ./UnitTests --gtest_filter=DicomWeb* && python /tmp/tutu.py < /tmp/tutu.json > /tmp/b.json && diff -i /tmp/a.json /tmp/b.json | 905 make -j4 && ./UnitTests --gtest_filter=DicomWeb* && python /tmp/tutu.py < /tmp/tutu.json > /tmp/b.json && diff -i /tmp/a.json /tmp/b.json |
858 | 906 |
859 */ | 907 */ |
860 | 908 |
861 TEST(DicomWebJson, Basic) | 909 TEST(DicomWebJson, Basic) |
862 { | 910 { |
863 std::string content; | 911 std::string content; |
864 Orthanc::SystemToolbox::ReadFile(content, "/home/jodogne/Subversion/orthanc-tests/Database/DummyCT.dcm"); | 912 Orthanc::SystemToolbox::ReadFile(content, "/home/jodogne/Subversion/orthanc-tests/Database/HierarchicalAnonymization/StructuredReports/IM0"); |
865 | 913 |
866 Orthanc::ParsedDicomFile dicom(content); | 914 Orthanc::ParsedDicomFile dicom(content); |
867 | 915 |
868 Orthanc::DicomJsonVisitor visitor; | 916 Orthanc::DicomJsonVisitor visitor; |
869 dicom.Apply(visitor); | 917 dicom.Apply(visitor); |