comparison OrthancFramework/UnitTestsSources/FromDcmtkTests.cpp @ 4734:b51c08bd5c38

added ITagVisitor::Action_Remove
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 05 Jul 2021 16:12:10 +0200
parents 4e2247df6327
children e17fdc43ef6c
comparison
equal deleted inserted replaced
4733:1db3b79d97bd 4734:b51c08bd5c38
59 #endif 59 #endif
60 60
61 #include <dcmtk/dcmdata/dcdeftag.h> 61 #include <dcmtk/dcmdata/dcdeftag.h>
62 #include <dcmtk/dcmdata/dcelem.h> 62 #include <dcmtk/dcmdata/dcelem.h>
63 #include <dcmtk/dcmdata/dcvrat.h> 63 #include <dcmtk/dcmdata/dcvrat.h>
64 #include <dcmtk/dcmdata/dcbytstr.h>
65 #include <dcmtk/dcmdata/dcvrss.h>
66 #include <dcmtk/dcmdata/dcvrfl.h>
64 67
65 #include <boost/algorithm/string/predicate.hpp> 68 #include <boost/algorithm/string/predicate.hpp>
66 #include <boost/lexical_cast.hpp> 69 #include <boost/lexical_cast.hpp>
67 70
68 #if ORTHANC_ENABLE_PUGIXML == 1 71 #if ORTHANC_ENABLE_PUGIXML == 1
2708 ASSERT_EQ("1.2.840.113704.1.111.7016.1342451220.40", vv[REL_SERIES_SEQ][0][STUDY_INSTANCE_UID].asString()); // kept 2711 ASSERT_EQ("1.2.840.113704.1.111.7016.1342451220.40", vv[REL_SERIES_SEQ][0][STUDY_INSTANCE_UID].asString()); // kept
2709 } 2712 }
2710 } 2713 }
2711 2714
2712 2715
2716 TEST(FromDcmtkBridge, VisitorRemoveTag)
2717 {
2718 class V : public ITagVisitor
2719 {
2720 private:
2721 uint32_t seen_;
2722
2723 public:
2724 V() : seen_(0)
2725 {
2726 }
2727
2728 unsigned int GetSeen() const
2729 {
2730 return seen_;
2731 }
2732
2733 virtual Action VisitNotSupported(const std::vector<DicomTag>& parentTags,
2734 const std::vector<size_t>& parentIndexes,
2735 const DicomTag& tag,
2736 ValueRepresentation vr) ORTHANC_OVERRIDE
2737 {
2738 seen_ |= (1 << 0);
2739
2740 if (parentTags.size() == 0u &&
2741 parentIndexes.size() == 0u &&
2742 DcmTagKey(tag.GetGroup(), tag.GetElement()) == DCM_PixelData)
2743 {
2744 return Action_Remove;
2745 }
2746 else
2747 {
2748 throw OrthancException(ErrorCode_InternalError);
2749 }
2750 }
2751
2752 virtual Action VisitEmptySequence(const std::vector<DicomTag>& parentTags,
2753 const std::vector<size_t>& parentIndexes,
2754 const DicomTag& tag) ORTHANC_OVERRIDE
2755 {
2756 seen_ |= (1 << 1);
2757
2758 if (parentTags.size() == 1u &&
2759 parentIndexes.size() == 1u &&
2760 parentTags[0] == DICOM_TAG_REFERENCED_IMAGE_SEQUENCE &&
2761 parentIndexes[0] == 0u &&
2762 DcmTagKey(tag.GetGroup(), tag.GetElement()) == DCM_ReferencedPatientSequence)
2763 {
2764 return Action_Remove;
2765 }
2766 else
2767 {
2768 throw OrthancException(ErrorCode_InternalError);
2769 }
2770 }
2771
2772 virtual Action VisitIntegers(const std::vector<DicomTag>& parentTags,
2773 const std::vector<size_t>& parentIndexes,
2774 const DicomTag& tag,
2775 ValueRepresentation vr,
2776 const std::vector<int64_t>& values) ORTHANC_OVERRIDE
2777 {
2778 seen_ |= (1 << 2);
2779
2780 if (parentTags.size() == 0u &&
2781 parentIndexes.size() == 0u &&
2782 DcmTagKey(tag.GetGroup(), tag.GetElement()) == DCM_TagAngleSecondAxis &&
2783 values.size() == 2 &&
2784 values[0] == 12 &&
2785 values[1] == 13)
2786 {
2787 return Action_Remove;
2788 }
2789 else
2790 {
2791 throw OrthancException(ErrorCode_InternalError);
2792 }
2793 }
2794
2795 virtual Action VisitDoubles(const std::vector<DicomTag>& parentTags,
2796 const std::vector<size_t>& parentIndexes,
2797 const DicomTag& tag,
2798 ValueRepresentation vr,
2799 const std::vector<double>& values) ORTHANC_OVERRIDE
2800 {
2801 seen_ |= (1 << 3);
2802
2803 if (parentTags.size() == 1u &&
2804 parentIndexes.size() == 1u &&
2805 parentTags[0] == DICOM_TAG_REFERENCED_IMAGE_SEQUENCE &&
2806 parentIndexes[0] == 0u &&
2807 DcmTagKey(tag.GetGroup(), tag.GetElement()) == DCM_ExaminedBodyThickness &&
2808 values.size() == 3 &&
2809 std::abs(values[0] - 42.0f) <= 0.001f &&
2810 std::abs(values[1] - 43.0f) <= 0.001f &&
2811 std::abs(values[2] - 47.0f) <= 0.001f)
2812 {
2813 return Action_Remove;
2814 }
2815 else
2816 {
2817 throw OrthancException(ErrorCode_InternalError);
2818 }
2819 }
2820
2821 virtual Action VisitAttributes(const std::vector<DicomTag>& parentTags,
2822 const std::vector<size_t>& parentIndexes,
2823 const DicomTag& tag,
2824 const std::vector<DicomTag>& values) ORTHANC_OVERRIDE
2825 {
2826 seen_ |= (1 << 4);
2827
2828 if (parentTags.size() == 1u &&
2829 parentIndexes.size() == 1u &&
2830 parentTags[0] == DICOM_TAG_REFERENCED_IMAGE_SEQUENCE &&
2831 parentIndexes[0] == 0u &&
2832 DcmTagKey(tag.GetGroup(), tag.GetElement()) == DCM_DimensionIndexPointer &&
2833 values.size() == 2 &&
2834 values[0] == DICOM_TAG_STUDY_DATE &&
2835 values[1] == DICOM_TAG_STUDY_TIME)
2836 {
2837 return Action_Remove;
2838 }
2839 else
2840 {
2841 throw OrthancException(ErrorCode_InternalError);
2842 }
2843 }
2844
2845 virtual Action VisitBinary(const std::vector<DicomTag>& parentTags,
2846 const std::vector<size_t>& parentIndexes,
2847 const DicomTag& tag,
2848 ValueRepresentation vr,
2849 const void* data,
2850 size_t size) ORTHANC_OVERRIDE
2851 {
2852 seen_ |= (1 << 5);
2853
2854 if (parentTags.size() == 1u &&
2855 parentIndexes.size() == 1u &&
2856 parentTags[0] == DICOM_TAG_REFERENCED_IMAGE_SEQUENCE &&
2857 parentIndexes[0] == 0u &&
2858 tag.GetGroup() == 0x0011 &&
2859 tag.GetElement() == 0x1311 &&
2860 size == 4u &&
2861 memcmp(data, "abcd", 4) == 0)
2862 {
2863 return Action_Remove;
2864 }
2865 else
2866 {
2867 throw OrthancException(ErrorCode_InternalError);
2868 }
2869 }
2870
2871 virtual Action VisitString(std::string& newValue,
2872 const std::vector<DicomTag>& parentTags,
2873 const std::vector<size_t>& parentIndexes,
2874 const DicomTag& tag,
2875 ValueRepresentation vr,
2876 const std::string& value) ORTHANC_OVERRIDE
2877 {
2878 seen_ |= (1 << 6);
2879 return Action_Remove;
2880 }
2881 };
2882
2883
2884 std::unique_ptr<ParsedDicomFile> dicom;
2885
2886 {
2887 Json::Value v = Json::objectValue;
2888 v["PatientName"] = "Hello";
2889 v["ReferencedSOPClassUID"] = "1.2.840.10008.5.1.4.1.1.4";
2890 v["ReferencedImageSequence"][0]["ReferencedSOPClassUID"] = "1.2.840.10008.5.1.4.1.1.4";
2891 v["ReferencedImageSequence"][0]["ReferencedSOPInstanceUID"] = "1.2.840.113619.2.176.2025.1499492.7040.1171286241.719";
2892 v["ReferencedImageSequence"][0]["ReferencedPatientSequence"] = Json::arrayValue; // Empty sequence
2893 v["ReferencedImageSequence"][0]["0011,1311"] = "abcd"; // Binary
2894
2895 dicom.reset(ParsedDicomFile::CreateFromJson(v, DicomFromJsonFlags_None, "PrivateCreator"));
2896
2897 {
2898 // Test value multiplicity (cannot be done using "ParsedDicomFile::CreateFromJson()")
2899 const int16_t a[] = { 12, 13 };
2900 std::unique_ptr<DcmSignedShort> s(new DcmSignedShort(DCM_TagAngleSecondAxis)); // VisitIntegers()
2901 ASSERT_TRUE(s->putSint16Array(a, 2).good());
2902 dicom->GetDcmtkObject().getDataset()->insert(s.release());
2903 }
2904
2905 {
2906 const float a[] = { 42, 43, 47 };
2907 std::unique_ptr<DcmFloatingPointSingle> s(new DcmFloatingPointSingle(DCM_ExaminedBodyThickness)); // VisitDoubles()
2908 ASSERT_TRUE(s->putFloat32Array(a, 3).good());
2909 DcmItem *item = NULL;
2910 ASSERT_TRUE(dicom->GetDcmtkObject().getDataset()->findAndGetSequenceItem(DCM_ReferencedImageSequence, item, 0).good());
2911 item->insert(s.release());
2912 }
2913
2914 {
2915 const uint16_t a[] = { 0x0008, 0x0020, 0x0008, 0x0030 };
2916 std::unique_ptr<DcmAttributeTag> s(new DcmAttributeTag(DCM_DimensionIndexPointer)); // VisitAttributes()
2917 ASSERT_TRUE(s->putUint16Array(a, 2).good());
2918 DcmItem *item = NULL;
2919 ASSERT_TRUE(dicom->GetDcmtkObject().getDataset()->findAndGetSequenceItem(DCM_ReferencedImageSequence, item, 0).good());
2920 item->insert(s.release());
2921 }
2922
2923 ASSERT_TRUE(dicom->GetDcmtkObject().getDataset()->insert(new DcmByteString(DCM_PixelData)).good()); // VisitNotSupported()
2924 }
2925
2926 {
2927 V visitor;
2928 dicom->Apply(visitor);
2929 ASSERT_EQ(127u, visitor.GetSeen()); // Make sure all the methods have been applied
2930 }
2931
2932 {
2933 Json::Value b;
2934 dicom->DatasetToJson(b, DicomToJsonFormat_Short, DicomToJsonFlags_Default, 0);
2935 ASSERT_EQ(Json::objectValue, b.type());
2936
2937 Json::Value::Members members = b.getMemberNames();
2938 ASSERT_EQ(1u, members.size());
2939 ASSERT_EQ("0008,1140", members[0]);
2940
2941 // Check that "b["0008,1140"]" is a sequence with one single empty object
2942 ASSERT_EQ(Json::arrayValue, b["0008,1140"].type());
2943 ASSERT_EQ(1u, b["0008,1140"].size());
2944 ASSERT_EQ(Json::objectValue, b["0008,1140"][0].type());
2945 ASSERT_EQ(0u, b["0008,1140"][0].size());
2946 }
2947 }
2948
2949
2713 2950
2714 #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1 2951 #if ORTHANC_ENABLE_DCMTK_TRANSCODING == 1
2715 2952
2716 #include "../Sources/DicomNetworking/DicomStoreUserConnection.h" 2953 #include "../Sources/DicomNetworking/DicomStoreUserConnection.h"
2717 #include "../Sources/DicomParsing/DcmtkTranscoder.h" 2954 #include "../Sources/DicomParsing/DcmtkTranscoder.h"