# HG changeset patch # User Sebastien Jodogne # Date 1605796770 -3600 # Node ID f62f685e0eb23c96f1e13884050f43beefb61352 # Parent 32e765ca71930471cb24146db4cb1706cc3802a0 avoid loading instance metadata on RTSTRUCT to avoid JSON parsing that freezes the browser diff -r 32e765ca7193 -r f62f685e0eb2 Applications/StoneWebViewer/WebApplication/app.js --- a/Applications/StoneWebViewer/WebApplication/app.js Thu Nov 19 12:15:21 2020 +0100 +++ b/Applications/StoneWebViewer/WebApplication/app.js Thu Nov 19 15:39:30 2020 +0100 @@ -611,7 +611,7 @@ stone.Setup(Module); stone.SetOrthancRoot('..', true); stone.SetSoftwareRendering(localStorage.settingSoftwareRendering == '1'); - console.warn('Native Stone properly intialized'); + console.warn('Stone properly initialized'); var study = getParameterFromUrl('study'); var series = getParameterFromUrl('series'); diff -r 32e765ca7193 -r f62f685e0eb2 Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp --- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Thu Nov 19 12:15:21 2020 +0100 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Thu Nov 19 15:39:30 2020 +0100 @@ -1857,16 +1857,28 @@ observer_->SignalFrameUpdated(*this, cursor_->GetCurrentIndex(), frames_->GetFramesCount(), DisplayedFrameQuality_None); } - + if (frames_->GetFramesCount() != 0) { - const std::string& sopInstanceUid = frames_->GetInstanceOfFrame(cursor_->GetCurrentIndex()).GetSopInstanceUid(); - + const OrthancStone::DicomInstanceParameters& centralInstance = frames_->GetInstanceOfFrame(cursor_->GetCurrentIndex()); + + /** + * Avoid loading metadata if we know that this cannot be a + * "true" image with pixel data. Retrieving instance metadata on + * RTSTRUCT can lead to very large JSON whose parsing will + * freeze the browser for several seconds. + **/ + const OrthancStone::SopClassUid uid = centralInstance.GetSopClassUid(); + if (uid != OrthancStone::SopClassUid_EncapsulatedPdf && + uid != OrthancStone::SopClassUid_RTDose && + uid != OrthancStone::SopClassUid_RTPlan && + uid != OrthancStone::SopClassUid_RTStruct && + GetSeriesThumbnailType(uid) != OrthancStone::SeriesThumbnailType_Video) { // Fetch the default windowing for the central instance const std::string uri = ("studies/" + frames_->GetStudyInstanceUid() + "/series/" + frames_->GetSeriesInstanceUid() + - "/instances/" + sopInstanceUid + "/metadata"); + "/instances/" + centralInstance.GetSopInstanceUid() + "/metadata"); loader_->ScheduleGetDicomWeb( boost::make_shared(Orthanc::DICOM_TAG_SOP_INSTANCE_UID), @@ -2423,7 +2435,7 @@ { int main(int argc, char const *argv[]) { - printf("OK\n"); + printf("Initializing Stone\n"); Orthanc::InitializeFramework("", true); Orthanc::Logging::EnableInfoLevel(true); //Orthanc::Logging::EnableTraceLevel(true); diff -r 32e765ca7193 -r f62f685e0eb2 OrthancStone/Sources/Loaders/SeriesThumbnailsLoader.cpp --- a/OrthancStone/Sources/Loaders/SeriesThumbnailsLoader.cpp Thu Nov 19 12:15:21 2020 +0100 +++ b/OrthancStone/Sources/Loaders/SeriesThumbnailsLoader.cpp Thu Nov 19 15:39:30 2020 +0100 @@ -45,25 +45,6 @@ namespace OrthancStone { - static SeriesThumbnailType ExtractSopClassUid(const std::string& sopClassUid) - { - if (sopClassUid == "1.2.840.10008.5.1.4.1.1.104.1") // Encapsulated PDF Storage - { - return SeriesThumbnailType_Pdf; - } - else if (sopClassUid == "1.2.840.10008.5.1.4.1.1.77.1.1.1" || // Video Endoscopic Image Storage - sopClassUid == "1.2.840.10008.5.1.4.1.1.77.1.2.1" || // Video Microscopic Image Storage - sopClassUid == "1.2.840.10008.5.1.4.1.1.77.1.4.1") // Video Photographic Image Storage - { - return SeriesThumbnailType_Video; - } - else - { - return SeriesThumbnailType_Unsupported; - } - } - - SeriesThumbnailsLoader::Thumbnail::Thumbnail(const std::string& image, const std::string& mime) : type_(SeriesThumbnailType_Image), @@ -259,7 +240,7 @@ if (ok) { - type = ExtractSopClassUid(sopClassUid); + type = GetSeriesThumbnailType(StringToSopClassUid(sopClassUid)); } } @@ -370,7 +351,7 @@ virtual void HandleSuccess(const std::string& body, const std::map& headers) ORTHANC_OVERRIDE { - SeriesThumbnailType type = ExtractSopClassUid(body); + SeriesThumbnailType type = GetSeriesThumbnailType(StringToSopClassUid(body)); if (type == SeriesThumbnailType_Pdf || type == SeriesThumbnailType_Video) diff -r 32e765ca7193 -r f62f685e0eb2 OrthancStone/Sources/Loaders/SeriesThumbnailsLoader.h --- a/OrthancStone/Sources/Loaders/SeriesThumbnailsLoader.h Thu Nov 19 12:15:21 2020 +0100 +++ b/OrthancStone/Sources/Loaders/SeriesThumbnailsLoader.h Thu Nov 19 15:39:30 2020 +0100 @@ -40,16 +40,6 @@ namespace OrthancStone { - enum SeriesThumbnailType - { - SeriesThumbnailType_NotLoaded = 1, // The remote server cannot decode this image - SeriesThumbnailType_Unsupported = 2, // The remote server cannot decode this image - SeriesThumbnailType_Pdf = 3, - SeriesThumbnailType_Video = 4, - SeriesThumbnailType_Image = 5 - }; - - class SeriesThumbnailsLoader : public IObservable, public ObserverBase diff -r 32e765ca7193 -r f62f685e0eb2 OrthancStone/Sources/StoneEnumerations.cpp --- a/OrthancStone/Sources/StoneEnumerations.cpp Thu Nov 19 12:15:21 2020 +0100 +++ b/OrthancStone/Sources/StoneEnumerations.cpp Thu Nov 19 15:39:30 2020 +0100 @@ -36,6 +36,30 @@ { return SopClassUid_RTDose; } + else if (s == "1.2.840.10008.5.1.4.1.1.481.5") + { + return SopClassUid_RTPlan; + } + else if (s == "1.2.840.10008.5.1.4.1.1.481.3") + { + return SopClassUid_RTStruct; + } + else if (s == "1.2.840.10008.5.1.4.1.1.104.1") + { + return SopClassUid_EncapsulatedPdf; + } + else if (s == "1.2.840.10008.5.1.4.1.1.77.1.1.1") + { + return SopClassUid_VideoEndoscopicImageStorage; + } + else if (s == "1.2.840.10008.5.1.4.1.1.77.1.2.1") + { + return SopClassUid_VideoMicroscopicImageStorage; + } + else if (s == "1.2.840.10008.5.1.4.1.1.77.1.4.1") + { + return SopClassUid_VideoPhotographicImageStorage; + } else { //LOG(INFO) << "Other SOP class UID: " << source; @@ -175,4 +199,22 @@ } } } + + + SeriesThumbnailType GetSeriesThumbnailType(SopClassUid sopClassUid) + { + switch (sopClassUid) + { + case SopClassUid_EncapsulatedPdf: + return SeriesThumbnailType_Pdf; + + case SopClassUid_VideoEndoscopicImageStorage: + case SopClassUid_VideoMicroscopicImageStorage: + case SopClassUid_VideoPhotographicImageStorage: + return SeriesThumbnailType_Video; + + default: + return SeriesThumbnailType_Unsupported; + } + } } diff -r 32e765ca7193 -r f62f685e0eb2 OrthancStone/Sources/StoneEnumerations.h --- a/OrthancStone/Sources/StoneEnumerations.h Thu Nov 19 12:15:21 2020 +0100 +++ b/OrthancStone/Sources/StoneEnumerations.h Thu Nov 19 15:39:30 2020 +0100 @@ -108,7 +108,22 @@ enum SopClassUid { SopClassUid_Other, - SopClassUid_RTDose + SopClassUid_RTDose, + SopClassUid_RTStruct, + SopClassUid_RTPlan, + SopClassUid_EncapsulatedPdf, + SopClassUid_VideoEndoscopicImageStorage, + SopClassUid_VideoMicroscopicImageStorage, + SopClassUid_VideoPhotographicImageStorage + }; + + enum SeriesThumbnailType + { + SeriesThumbnailType_NotLoaded = 1, // The remote server cannot decode this image + SeriesThumbnailType_Unsupported = 2, // The remote server cannot decode this image + SeriesThumbnailType_Pdf = 3, + SeriesThumbnailType_Video = 4, + SeriesThumbnailType_Image = 5 }; enum BitmapAnchor @@ -156,4 +171,6 @@ unsigned int bitmapWidth, unsigned int bitmapHeight, unsigned int border = 0); + + SeriesThumbnailType GetSeriesThumbnailType(SopClassUid sopClassUid); } diff -r 32e765ca7193 -r f62f685e0eb2 UnitTestsSources/UnitTestsMain.cpp --- a/UnitTestsSources/UnitTestsMain.cpp Thu Nov 19 12:15:21 2020 +0100 +++ b/UnitTestsSources/UnitTestsMain.cpp Thu Nov 19 15:39:30 2020 +0100 @@ -940,6 +940,29 @@ } +TEST(Enumerations, Basic) +{ + using namespace OrthancStone; + ASSERT_EQ(SopClassUid_EncapsulatedPdf, StringToSopClassUid("1.2.840.10008.5.1.4.1.1.104.1")); + ASSERT_EQ(SopClassUid_RTStruct, StringToSopClassUid("1.2.840.10008.5.1.4.1.1.481.3")); + ASSERT_EQ(SopClassUid_RTDose, StringToSopClassUid("1.2.840.10008.5.1.4.1.1.481.2")); + ASSERT_EQ(SopClassUid_RTPlan, StringToSopClassUid("1.2.840.10008.5.1.4.1.1.481.5")); + ASSERT_EQ(SopClassUid_VideoEndoscopicImageStorage, StringToSopClassUid("1.2.840.10008.5.1.4.1.1.77.1.1.1")); + ASSERT_EQ(SopClassUid_VideoMicroscopicImageStorage, StringToSopClassUid("1.2.840.10008.5.1.4.1.1.77.1.2.1")); + ASSERT_EQ(SopClassUid_VideoPhotographicImageStorage, StringToSopClassUid("1.2.840.10008.5.1.4.1.1.77.1.4.1")); + ASSERT_EQ(SopClassUid_Other, StringToSopClassUid("nope")); + + ASSERT_EQ(SeriesThumbnailType_Pdf, GetSeriesThumbnailType(SopClassUid_EncapsulatedPdf)); + ASSERT_EQ(SeriesThumbnailType_Video, GetSeriesThumbnailType(SopClassUid_VideoEndoscopicImageStorage)); + ASSERT_EQ(SeriesThumbnailType_Video, GetSeriesThumbnailType(SopClassUid_VideoMicroscopicImageStorage)); + ASSERT_EQ(SeriesThumbnailType_Video, GetSeriesThumbnailType(SopClassUid_VideoPhotographicImageStorage)); + ASSERT_EQ(SeriesThumbnailType_Unsupported, GetSeriesThumbnailType(SopClassUid_Other)); + ASSERT_EQ(SeriesThumbnailType_Unsupported, GetSeriesThumbnailType(SopClassUid_RTDose)); + ASSERT_EQ(SeriesThumbnailType_Unsupported, GetSeriesThumbnailType(SopClassUid_RTStruct)); + ASSERT_EQ(SeriesThumbnailType_Unsupported, GetSeriesThumbnailType(SopClassUid_RTPlan)); +} + + int main(int argc, char **argv) { Orthanc::Logging::Initialize();