comparison OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp @ 4769:9da6ca57a977

IDecodedFrameHandler can access full ParsedDicomFile instead of the DicomMap summary
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 25 Aug 2021 15:20:48 +0200
parents 2b4da0ee6b73
children 3b78ba359db3
comparison
equal deleted inserted replaced
4768:a046e91cc76f 4769:9da6ca57a977
661 public: 661 public:
662 virtual ~IDecodedFrameHandler() 662 virtual ~IDecodedFrameHandler()
663 { 663 {
664 } 664 }
665 665
666 // "dicom" is non-NULL iff. "RequiresDicomTags() == true"
666 virtual void Handle(RestApiGetCall& call, 667 virtual void Handle(RestApiGetCall& call,
667 std::unique_ptr<ImageAccessor>& decoded, 668 std::unique_ptr<ImageAccessor>& decoded,
668 const DicomMap& dicom) = 0; 669 const ParsedDicomFile* dicom) = 0;
669 670
670 virtual bool RequiresDicomTags() const = 0; 671 virtual bool RequiresDicomTags() const = 0;
671 672
672 static void Apply(RestApiGetCall& call, 673 static void Apply(RestApiGetCall& call,
673 IDecodedFrameHandler& handler, 674 IDecodedFrameHandler& handler,
774 catch (boost::bad_lexical_cast&) 775 catch (boost::bad_lexical_cast&)
775 { 776 {
776 return; 777 return;
777 } 778 }
778 779
779 DicomMap dicom;
780 std::unique_ptr<ImageAccessor> decoded; 780 std::unique_ptr<ImageAccessor> decoded;
781 781
782 try 782 try
783 { 783 {
784 std::string publicId = call.GetUriComponent("id", ""); 784 std::string publicId = call.GetUriComponent("id", "");
797 * Retrieve a summary of the DICOM tags, which is 797 * Retrieve a summary of the DICOM tags, which is
798 * necessary to deal with MONOCHROME1 photometric 798 * necessary to deal with MONOCHROME1 photometric
799 * interpretation, and with windowing parameters. 799 * interpretation, and with windowing parameters.
800 **/ 800 **/
801 ServerContext::DicomCacheLocker locker(context, publicId); 801 ServerContext::DicomCacheLocker locker(context, publicId);
802 OrthancConfiguration::DefaultExtractDicomSummary(dicom, locker.GetDicom()); 802 handler.Handle(call, decoded, &locker.GetDicom());
803 }
804 else
805 {
806 handler.Handle(call, decoded, NULL);
803 } 807 }
804 } 808 }
805 catch (OrthancException& e) 809 catch (OrthancException& e)
806 { 810 {
807 if (e.GetErrorCode() == ErrorCode_ParameterOutOfRange || 811 if (e.GetErrorCode() == ErrorCode_ParameterOutOfRange ||
821 call.GetOutput().Redirect(root + "app/images/unsupported.png"); 825 call.GetOutput().Redirect(root + "app/images/unsupported.png");
822 } 826 }
823 return; 827 return;
824 } 828 }
825 829
826 handler.Handle(call, decoded, dicom);
827 } 830 }
828 831
829 832
830 static void DefaultHandler(RestApiGetCall& call, 833 static void DefaultHandler(RestApiGetCall& call,
831 std::unique_ptr<ImageAccessor>& decoded, 834 std::unique_ptr<ImageAccessor>& decoded,
863 { 866 {
864 } 867 }
865 868
866 virtual void Handle(RestApiGetCall& call, 869 virtual void Handle(RestApiGetCall& call,
867 std::unique_ptr<ImageAccessor>& decoded, 870 std::unique_ptr<ImageAccessor>& decoded,
868 const DicomMap& dicom) ORTHANC_OVERRIDE 871 const ParsedDicomFile* dicom) ORTHANC_OVERRIDE
869 { 872 {
870 bool invert = false; 873 bool invert = false;
871 874
872 if (mode_ == ImageExtractionMode_Preview) 875 if (mode_ == ImageExtractionMode_Preview)
873 { 876 {
874 DicomImageInformation info(dicom); 877 if (dicom == NULL)
878 {
879 throw OrthancException(ErrorCode_InternalError);
880 }
881
882 DicomMap tags;
883 OrthancConfiguration::DefaultExtractDicomSummary(tags, *dicom);
884
885 DicomImageInformation info(tags);
875 invert = (info.GetPhotometricInterpretation() == PhotometricInterpretation_Monochrome1); 886 invert = (info.GetPhotometricInterpretation() == PhotometricInterpretation_Monochrome1);
876 } 887 }
877 888
878 DefaultHandler(call, decoded, mode_, invert); 889 DefaultHandler(call, decoded, mode_, invert);
879 } 890 }
891 static void GetDicomParameters(bool& invert, 902 static void GetDicomParameters(bool& invert,
892 float& rescaleSlope, 903 float& rescaleSlope,
893 float& rescaleIntercept, 904 float& rescaleIntercept,
894 float& windowWidth, 905 float& windowWidth,
895 float& windowCenter, 906 float& windowCenter,
896 const DicomMap& dicom) 907 const ParsedDicomFile& dicom)
897 { 908 {
898 DicomImageInformation info(dicom); 909 DicomMap tags;
910 OrthancConfiguration::DefaultExtractDicomSummary(tags, dicom);
911
912 DicomImageInformation info(tags);
899 913
900 invert = (info.GetPhotometricInterpretation() == PhotometricInterpretation_Monochrome1); 914 invert = (info.GetPhotometricInterpretation() == PhotometricInterpretation_Monochrome1);
901 915
902 rescaleSlope = 1.0f; 916 rescaleSlope = 1.0f;
903 rescaleIntercept = 0.0f; 917 rescaleIntercept = 0.0f;
904 918
905 if (dicom.HasTag(Orthanc::DICOM_TAG_RESCALE_SLOPE) && 919 if (dicom.HasTag(Orthanc::DICOM_TAG_RESCALE_SLOPE) &&
906 dicom.HasTag(Orthanc::DICOM_TAG_RESCALE_INTERCEPT)) 920 dicom.HasTag(Orthanc::DICOM_TAG_RESCALE_INTERCEPT))
907 { 921 {
908 dicom.ParseFloat(rescaleSlope, Orthanc::DICOM_TAG_RESCALE_SLOPE); 922 tags.ParseFloat(rescaleSlope, Orthanc::DICOM_TAG_RESCALE_SLOPE);
909 dicom.ParseFloat(rescaleIntercept, Orthanc::DICOM_TAG_RESCALE_INTERCEPT); 923 tags.ParseFloat(rescaleIntercept, Orthanc::DICOM_TAG_RESCALE_INTERCEPT);
910 } 924 }
911 925
912 windowWidth = static_cast<float>(1 << info.GetBitsStored()) * rescaleSlope; 926 windowWidth = static_cast<float>(1 << info.GetBitsStored()) * rescaleSlope;
913 windowCenter = windowWidth / 2.0f + rescaleIntercept; 927 windowCenter = windowWidth / 2.0f + rescaleIntercept;
914 928
915 if (dicom.HasTag(Orthanc::DICOM_TAG_WINDOW_CENTER) && 929 if (tags.HasTag(Orthanc::DICOM_TAG_WINDOW_CENTER) &&
916 dicom.HasTag(Orthanc::DICOM_TAG_WINDOW_WIDTH)) 930 tags.HasTag(Orthanc::DICOM_TAG_WINDOW_WIDTH))
917 { 931 {
918 dicom.ParseFirstFloat(windowCenter, Orthanc::DICOM_TAG_WINDOW_CENTER); 932 tags.ParseFirstFloat(windowCenter, Orthanc::DICOM_TAG_WINDOW_CENTER);
919 dicom.ParseFirstFloat(windowWidth, Orthanc::DICOM_TAG_WINDOW_WIDTH); 933 tags.ParseFirstFloat(windowWidth, Orthanc::DICOM_TAG_WINDOW_WIDTH);
920 } 934 }
921 } 935 }
922 936
923 static void GetUserArguments(float& windowWidth /* inout */, 937 static void GetUserArguments(float& windowWidth /* inout */,
924 float& windowCenter /* inout */, 938 float& windowCenter /* inout */,
1016 1030
1017 1031
1018 public: 1032 public:
1019 virtual void Handle(RestApiGetCall& call, 1033 virtual void Handle(RestApiGetCall& call,
1020 std::unique_ptr<ImageAccessor>& decoded, 1034 std::unique_ptr<ImageAccessor>& decoded,
1021 const DicomMap& dicom) ORTHANC_OVERRIDE 1035 const ParsedDicomFile* dicom) ORTHANC_OVERRIDE
1022 { 1036 {
1037 if (dicom == NULL)
1038 {
1039 throw OrthancException(ErrorCode_InternalError);
1040 }
1041
1023 bool invert; 1042 bool invert;
1024 float rescaleSlope, rescaleIntercept, windowWidth, windowCenter; 1043 float rescaleSlope, rescaleIntercept, windowWidth, windowCenter;
1025 GetDicomParameters(invert, rescaleSlope, rescaleIntercept, windowWidth, windowCenter, dicom); 1044 GetDicomParameters(invert, rescaleSlope, rescaleIntercept, windowWidth, windowCenter, *dicom);
1026 1045
1027 unsigned int argWidth, argHeight; 1046 unsigned int argWidth, argHeight;
1028 bool smooth; 1047 bool smooth;
1029 GetUserArguments(windowWidth, windowCenter, argWidth, argHeight, smooth, call); 1048 GetUserArguments(windowWidth, windowCenter, argWidth, argHeight, smooth, call);
1030 1049