comparison OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.cpp @ 4682:d38a7040474a

FromDcmtkBridge::RemovePath() and FromDcmtkBridge::ReplacePath()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 07 Jun 2021 18:35:46 +0200
parents 72af097bb92b
children 7182f5732480
comparison
equal deleted inserted replaced
4681:c5528c7847a6 4682:d38a7040474a
2792 sopInstanceUid.assign(c); 2792 sopInstanceUid.assign(c);
2793 } 2793 }
2794 2794
2795 DicomMap::LogMissingTagsForStore(patientId, studyInstanceUid, seriesInstanceUid, sopInstanceUid); 2795 DicomMap::LogMissingTagsForStore(patientId, studyInstanceUid, seriesInstanceUid, sopInstanceUid);
2796 } 2796 }
2797
2798
2799 static void ApplyInternal(FromDcmtkBridge::IDicomPathVisitor& visitor,
2800 DcmItem& item,
2801 const DicomPath& path,
2802 size_t level)
2803 {
2804 if (level == path.GetPrefixLength())
2805 {
2806 visitor.Visit(item, path.GetFinalTag());
2807 }
2808 else
2809 {
2810 const DicomTag& tmp = path.GetPrefixTag(level);
2811 DcmTagKey tag(tmp.GetGroup(), tmp.GetElement());
2812
2813 DcmSequenceOfItems *sequence = NULL;
2814 if (item.findAndGetSequence(tag, sequence).good() &&
2815 sequence != NULL)
2816 {
2817 for (unsigned long i = 0; i < sequence->card(); i++)
2818 {
2819 if (path.IsPrefixUniversal(level) ||
2820 path.GetPrefixIndex(level) == static_cast<size_t>(i))
2821 {
2822 DcmItem *child = sequence->getItem(i);
2823 if (child != NULL)
2824 {
2825 ApplyInternal(visitor, *child, path, level + 1);
2826 }
2827 }
2828 }
2829 }
2830 }
2831 }
2832
2833
2834 void FromDcmtkBridge::Apply(IDicomPathVisitor& visitor,
2835 DcmDataset& dataset,
2836 const DicomPath& path)
2837 {
2838 ApplyInternal(visitor, dataset, path, 0);
2839 }
2840
2841
2842 void FromDcmtkBridge::RemovePath(DcmDataset& dataset,
2843 const DicomPath& path)
2844 {
2845 class Visitor : public FromDcmtkBridge::IDicomPathVisitor
2846 {
2847 public:
2848 virtual void Visit(DcmItem& item,
2849 const DicomTag& tag) ORTHANC_OVERRIDE
2850 {
2851 DcmTagKey tmp(tag.GetGroup(), tag.GetElement());
2852 std::unique_ptr<DcmElement> removed(item.remove(tmp));
2853 }
2854 };
2855
2856 Visitor visitor;
2857 Apply(visitor, dataset, path);
2858 }
2859
2860
2861 void FromDcmtkBridge::ReplacePath(DcmDataset& dataset,
2862 const DicomPath& path,
2863 const DcmElement& element)
2864 {
2865 class Visitor : public FromDcmtkBridge::IDicomPathVisitor
2866 {
2867 private:
2868 std::unique_ptr<DcmElement> element_;
2869
2870 public:
2871 Visitor(const DcmElement& element) :
2872 element_(dynamic_cast<DcmElement*>(element.clone()))
2873 {
2874 if (element_.get() == NULL)
2875 {
2876 throw OrthancException(ErrorCode_InternalError, "Cannot clone DcmElement");
2877 }
2878 }
2879
2880 virtual void Visit(DcmItem& item,
2881 const DicomTag& tag) ORTHANC_OVERRIDE
2882 {
2883 std::unique_ptr<DcmElement> cloned(dynamic_cast<DcmElement*>(element_->clone()));
2884 if (cloned.get() == NULL)
2885 {
2886 throw OrthancException(ErrorCode_InternalError, "Cannot clone DcmElement");
2887 }
2888 else
2889 {
2890 DcmTagKey tmp(tag.GetGroup(), tag.GetElement());
2891 if (!item.insert(cloned.release(), OFTrue /* replace old */).good())
2892 {
2893 throw OrthancException(ErrorCode_InternalError, "Cannot replace an element");
2894 }
2895 }
2896 }
2897 };
2898
2899 DcmTagKey tmp(path.GetFinalTag().GetGroup(), path.GetFinalTag().GetElement());
2900
2901 if (element.getTag() != tmp)
2902 {
2903 throw OrthancException(ErrorCode_ParameterOutOfRange,
2904 "The final tag must be the same as the tag of the element during a replacement");
2905 }
2906 else
2907 {
2908 Visitor visitor(element);
2909 Apply(visitor, dataset, path);
2910 }
2911 }
2797 } 2912 }
2798 2913
2799 2914
2800 #include "./FromDcmtkBridge_TransferSyntaxes.impl.h" 2915 #include "./FromDcmtkBridge_TransferSyntaxes.impl.h"