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);