Mercurial > hg > orthanc
comparison OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp @ 4785:61da49321754 openssl-3.x
integration mainline->openssl-3.x
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Mon, 30 Aug 2021 22:21:24 +0200 |
parents | 4b721432fa67 3b78ba359db3 |
children | 70d2a97ca8cb |
comparison
equal
deleted
inserted
replaced
4760:b2417ac5055a | 4785:61da49321754 |
---|---|
649 public: | 649 public: |
650 virtual ~IDecodedFrameHandler() | 650 virtual ~IDecodedFrameHandler() |
651 { | 651 { |
652 } | 652 } |
653 | 653 |
654 // "dicom" is non-NULL iff. "RequiresDicomTags() == true" | |
654 virtual void Handle(RestApiGetCall& call, | 655 virtual void Handle(RestApiGetCall& call, |
655 std::unique_ptr<ImageAccessor>& decoded, | 656 std::unique_ptr<ImageAccessor>& decoded, |
656 const DicomMap& dicom) = 0; | 657 const ParsedDicomFile* dicom, |
658 unsigned int frame) = 0; | |
657 | 659 |
658 virtual bool RequiresDicomTags() const = 0; | 660 virtual bool RequiresDicomTags() const = 0; |
659 | 661 |
660 static void Apply(RestApiGetCall& call, | 662 static void Apply(RestApiGetCall& call, |
661 IDecodedFrameHandler& handler, | 663 IDecodedFrameHandler& handler, |
762 catch (boost::bad_lexical_cast&) | 764 catch (boost::bad_lexical_cast&) |
763 { | 765 { |
764 return; | 766 return; |
765 } | 767 } |
766 | 768 |
767 DicomMap dicom; | |
768 std::unique_ptr<ImageAccessor> decoded; | 769 std::unique_ptr<ImageAccessor> decoded; |
769 | 770 |
770 try | 771 try |
771 { | 772 { |
772 std::string publicId = call.GetUriComponent("id", ""); | 773 std::string publicId = call.GetUriComponent("id", ""); |
785 * Retrieve a summary of the DICOM tags, which is | 786 * Retrieve a summary of the DICOM tags, which is |
786 * necessary to deal with MONOCHROME1 photometric | 787 * necessary to deal with MONOCHROME1 photometric |
787 * interpretation, and with windowing parameters. | 788 * interpretation, and with windowing parameters. |
788 **/ | 789 **/ |
789 ServerContext::DicomCacheLocker locker(context, publicId); | 790 ServerContext::DicomCacheLocker locker(context, publicId); |
790 OrthancConfiguration::DefaultExtractDicomSummary(dicom, locker.GetDicom()); | 791 handler.Handle(call, decoded, &locker.GetDicom(), frame); |
792 } | |
793 else | |
794 { | |
795 handler.Handle(call, decoded, NULL, frame); | |
791 } | 796 } |
792 } | 797 } |
793 catch (OrthancException& e) | 798 catch (OrthancException& e) |
794 { | 799 { |
795 if (e.GetErrorCode() == ErrorCode_ParameterOutOfRange || | 800 if (e.GetErrorCode() == ErrorCode_ParameterOutOfRange || |
809 call.GetOutput().Redirect(root + "app/images/unsupported.png"); | 814 call.GetOutput().Redirect(root + "app/images/unsupported.png"); |
810 } | 815 } |
811 return; | 816 return; |
812 } | 817 } |
813 | 818 |
814 handler.Handle(call, decoded, dicom); | |
815 } | 819 } |
816 | 820 |
817 | 821 |
818 static void DefaultHandler(RestApiGetCall& call, | 822 static void DefaultHandler(RestApiGetCall& call, |
819 std::unique_ptr<ImageAccessor>& decoded, | 823 std::unique_ptr<ImageAccessor>& decoded, |
851 { | 855 { |
852 } | 856 } |
853 | 857 |
854 virtual void Handle(RestApiGetCall& call, | 858 virtual void Handle(RestApiGetCall& call, |
855 std::unique_ptr<ImageAccessor>& decoded, | 859 std::unique_ptr<ImageAccessor>& decoded, |
856 const DicomMap& dicom) ORTHANC_OVERRIDE | 860 const ParsedDicomFile* dicom, |
861 unsigned int frame) ORTHANC_OVERRIDE | |
857 { | 862 { |
858 bool invert = false; | 863 bool invert = false; |
859 | 864 |
860 if (mode_ == ImageExtractionMode_Preview) | 865 if (mode_ == ImageExtractionMode_Preview) |
861 { | 866 { |
862 DicomImageInformation info(dicom); | 867 if (dicom == NULL) |
868 { | |
869 throw OrthancException(ErrorCode_InternalError); | |
870 } | |
871 | |
872 DicomMap tags; | |
873 OrthancConfiguration::DefaultExtractDicomSummary(tags, *dicom); | |
874 | |
875 DicomImageInformation info(tags); | |
863 invert = (info.GetPhotometricInterpretation() == PhotometricInterpretation_Monochrome1); | 876 invert = (info.GetPhotometricInterpretation() == PhotometricInterpretation_Monochrome1); |
864 } | 877 } |
865 | 878 |
866 DefaultHandler(call, decoded, mode_, invert); | 879 DefaultHandler(call, decoded, mode_, invert); |
867 } | 880 } |
874 | 887 |
875 | 888 |
876 class RenderedFrameHandler : public IDecodedFrameHandler | 889 class RenderedFrameHandler : public IDecodedFrameHandler |
877 { | 890 { |
878 private: | 891 private: |
879 static void GetDicomParameters(bool& invert, | 892 static void GetUserArguments(double& windowWidth /* inout */, |
880 float& rescaleSlope, | 893 double& windowCenter /* inout */, |
881 float& rescaleIntercept, | |
882 float& windowWidth, | |
883 float& windowCenter, | |
884 const DicomMap& dicom) | |
885 { | |
886 DicomImageInformation info(dicom); | |
887 | |
888 invert = (info.GetPhotometricInterpretation() == PhotometricInterpretation_Monochrome1); | |
889 | |
890 rescaleSlope = 1.0f; | |
891 rescaleIntercept = 0.0f; | |
892 | |
893 if (dicom.HasTag(Orthanc::DICOM_TAG_RESCALE_SLOPE) && | |
894 dicom.HasTag(Orthanc::DICOM_TAG_RESCALE_INTERCEPT)) | |
895 { | |
896 dicom.ParseFloat(rescaleSlope, Orthanc::DICOM_TAG_RESCALE_SLOPE); | |
897 dicom.ParseFloat(rescaleIntercept, Orthanc::DICOM_TAG_RESCALE_INTERCEPT); | |
898 } | |
899 | |
900 windowWidth = static_cast<float>(1 << info.GetBitsStored()) * rescaleSlope; | |
901 windowCenter = windowWidth / 2.0f + rescaleIntercept; | |
902 | |
903 if (dicom.HasTag(Orthanc::DICOM_TAG_WINDOW_CENTER) && | |
904 dicom.HasTag(Orthanc::DICOM_TAG_WINDOW_WIDTH)) | |
905 { | |
906 dicom.ParseFirstFloat(windowCenter, Orthanc::DICOM_TAG_WINDOW_CENTER); | |
907 dicom.ParseFirstFloat(windowWidth, Orthanc::DICOM_TAG_WINDOW_WIDTH); | |
908 } | |
909 } | |
910 | |
911 static void GetUserArguments(float& windowWidth /* inout */, | |
912 float& windowCenter /* inout */, | |
913 unsigned int& argWidth, | 894 unsigned int& argWidth, |
914 unsigned int& argHeight, | 895 unsigned int& argHeight, |
915 bool& smooth, | 896 bool& smooth, |
916 const RestApiGetCall& call) | 897 const RestApiGetCall& call) |
917 { | 898 { |
919 static const char* ARG_WINDOW_WIDTH = "window-width"; | 900 static const char* ARG_WINDOW_WIDTH = "window-width"; |
920 static const char* ARG_WIDTH = "width"; | 901 static const char* ARG_WIDTH = "width"; |
921 static const char* ARG_HEIGHT = "height"; | 902 static const char* ARG_HEIGHT = "height"; |
922 static const char* ARG_SMOOTH = "smooth"; | 903 static const char* ARG_SMOOTH = "smooth"; |
923 | 904 |
924 if (call.HasArgument(ARG_WINDOW_WIDTH)) | 905 if (call.HasArgument(ARG_WINDOW_WIDTH) && |
925 { | 906 !SerializationToolbox::ParseDouble(windowWidth, call.GetArgument(ARG_WINDOW_WIDTH, ""))) |
926 try | 907 { |
927 { | 908 throw OrthancException(ErrorCode_ParameterOutOfRange, |
928 windowWidth = boost::lexical_cast<float>(call.GetArgument(ARG_WINDOW_WIDTH, "")); | 909 "Bad value for argument: " + std::string(ARG_WINDOW_WIDTH)); |
929 } | 910 } |
930 catch (boost::bad_lexical_cast&) | 911 |
931 { | 912 if (call.HasArgument(ARG_WINDOW_CENTER) && |
932 throw OrthancException(ErrorCode_ParameterOutOfRange, | 913 !SerializationToolbox::ParseDouble(windowCenter, call.GetArgument(ARG_WINDOW_CENTER, ""))) |
933 "Bad value for argument: " + std::string(ARG_WINDOW_WIDTH)); | 914 { |
934 } | 915 throw OrthancException(ErrorCode_ParameterOutOfRange, |
935 } | 916 "Bad value for argument: " + std::string(ARG_WINDOW_CENTER)); |
936 | |
937 if (call.HasArgument(ARG_WINDOW_CENTER)) | |
938 { | |
939 try | |
940 { | |
941 windowCenter = boost::lexical_cast<float>(call.GetArgument(ARG_WINDOW_CENTER, "")); | |
942 } | |
943 catch (boost::bad_lexical_cast&) | |
944 { | |
945 throw OrthancException(ErrorCode_ParameterOutOfRange, | |
946 "Bad value for argument: " + std::string(ARG_WINDOW_CENTER)); | |
947 } | |
948 } | 917 } |
949 | 918 |
950 argWidth = 0; | 919 argWidth = 0; |
951 argHeight = 0; | 920 argHeight = 0; |
952 | 921 |
1004 | 973 |
1005 | 974 |
1006 public: | 975 public: |
1007 virtual void Handle(RestApiGetCall& call, | 976 virtual void Handle(RestApiGetCall& call, |
1008 std::unique_ptr<ImageAccessor>& decoded, | 977 std::unique_ptr<ImageAccessor>& decoded, |
1009 const DicomMap& dicom) ORTHANC_OVERRIDE | 978 const ParsedDicomFile* dicom, |
1010 { | 979 unsigned int frame) ORTHANC_OVERRIDE |
1011 bool invert; | 980 { |
1012 float rescaleSlope, rescaleIntercept, windowWidth, windowCenter; | 981 if (dicom == NULL) |
1013 GetDicomParameters(invert, rescaleSlope, rescaleIntercept, windowWidth, windowCenter, dicom); | 982 { |
1014 | 983 throw OrthancException(ErrorCode_InternalError); |
984 } | |
985 | |
986 PhotometricInterpretation photometric; | |
987 const bool invert = (dicom->LookupPhotometricInterpretation(photometric) && | |
988 photometric == PhotometricInterpretation_Monochrome1); | |
989 | |
990 double rescaleIntercept, rescaleSlope, windowCenter, windowWidth; | |
991 dicom->GetRescale(rescaleIntercept, rescaleSlope, frame); | |
992 dicom->GetDefaultWindowing(windowCenter, windowWidth, frame); | |
993 | |
1015 unsigned int argWidth, argHeight; | 994 unsigned int argWidth, argHeight; |
1016 bool smooth; | 995 bool smooth; |
1017 GetUserArguments(windowWidth, windowCenter, argWidth, argHeight, smooth, call); | 996 GetUserArguments(windowWidth, windowCenter, argWidth, argHeight, smooth, call); |
1018 | 997 |
1019 unsigned int targetWidth = decoded->GetWidth(); | 998 unsigned int targetWidth = decoded->GetWidth(); |
1079 if (windowWidth <= 1.0f) | 1058 if (windowWidth <= 1.0f) |
1080 { | 1059 { |
1081 windowWidth = 1; | 1060 windowWidth = 1; |
1082 } | 1061 } |
1083 | 1062 |
1084 if (std::abs(rescaleSlope) <= 0.1f) | 1063 if (std::abs(rescaleSlope) <= 0.1) |
1085 { | 1064 { |
1086 rescaleSlope = 0.1f; | 1065 rescaleSlope = 0.1; |
1087 } | 1066 } |
1088 | 1067 |
1089 const float scaling = 255.0f * rescaleSlope / windowWidth; | 1068 const double scaling = 255.0 * rescaleSlope / windowWidth; |
1090 const float offset = (rescaleIntercept - windowCenter + windowWidth / 2.0f) / rescaleSlope; | 1069 const double offset = (rescaleIntercept - windowCenter + windowWidth / 2.0) / rescaleSlope; |
1091 | 1070 |
1092 std::unique_ptr<ImageAccessor> rescaled(new Image(PixelFormat_Grayscale8, decoded->GetWidth(), decoded->GetHeight(), false)); | 1071 std::unique_ptr<ImageAccessor> rescaled(new Image(PixelFormat_Grayscale8, decoded->GetWidth(), decoded->GetHeight(), false)); |
1093 ImageProcessing::ShiftScale(*rescaled, converted, offset, scaling, false); | 1072 ImageProcessing::ShiftScale(*rescaled, converted, static_cast<float>(offset), static_cast<float>(scaling), false); |
1094 | 1073 |
1095 if (targetWidth == decoded->GetWidth() && | 1074 if (targetWidth == decoded->GetWidth() && |
1096 targetHeight == decoded->GetHeight()) | 1075 targetHeight == decoded->GetHeight()) |
1097 { | 1076 { |
1098 DefaultHandler(call, rescaled, ImageExtractionMode_UInt8, invert); | 1077 DefaultHandler(call, rescaled, ImageExtractionMode_UInt8, invert); |