comparison Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp @ 1675:6fa05252b085

don't load low-quality image if the parsed dicom file is cached by the oracle
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 23 Nov 2020 18:09:14 +0100
parents 0621e523b670
children 5e76d5e8167a
comparison
equal deleted inserted replaced
1674:0621e523b670 1675:6fa05252b085
582 582
583 public: 583 public:
584 FramesCache() 584 FramesCache()
585 { 585 {
586 SetMaximumSize(100 * 1024 * 1024); // 100 MB 586 SetMaximumSize(100 * 1024 * 1024); // 100 MB
587 //SetMaximumSize(1); // DISABLE CACHE
587 } 588 }
588 589
589 size_t GetMaximumSize() 590 size_t GetMaximumSize()
590 { 591 {
591 return cache_.GetMaximumSize(); 592 return cache_.GetMaximumSize();
1255 { 1256 {
1256 } 1257 }
1257 1258
1258 virtual void Handle(const OrthancStone::ParseDicomSuccessMessage& message) const ORTHANC_OVERRIDE 1259 virtual void Handle(const OrthancStone::ParseDicomSuccessMessage& message) const ORTHANC_OVERRIDE
1259 { 1260 {
1261 Apply(GetViewport(), message.GetDicom(), sopInstanceUid_, frameNumber_);
1262
1263 if (isPrefetch_)
1264 {
1265 GetViewport().ScheduleNextPrefetch();
1266 }
1267 }
1268
1269 static void Apply(ViewerViewport& viewport,
1270 const Orthanc::ParsedDicomFile& dicom,
1271 const std::string& sopInstanceUid,
1272 unsigned int frameNumber)
1273 {
1260 Orthanc::DicomMap tags; 1274 Orthanc::DicomMap tags;
1261 message.GetDicom().ExtractDicomSummary(tags, ORTHANC_STONE_MAX_TAG_LENGTH); 1275 dicom.ExtractDicomSummary(tags, ORTHANC_STONE_MAX_TAG_LENGTH);
1262 1276
1263 std::string s; 1277 std::string s;
1264 if (!tags.LookupStringValue(s, Orthanc::DICOM_TAG_SOP_INSTANCE_UID, false)) 1278 if (!tags.LookupStringValue(s, Orthanc::DICOM_TAG_SOP_INSTANCE_UID, false))
1265 { 1279 {
1266 // Safety check 1280 // Safety check
1267 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 1281 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
1268 } 1282 }
1269 1283
1270 std::unique_ptr<Orthanc::ImageAccessor> frame(message.GetDicom().DecodeFrame(frameNumber_)); 1284 std::unique_ptr<Orthanc::ImageAccessor> frame(dicom.DecodeFrame(frameNumber));
1271 1285
1272 if (frame.get() == NULL) 1286 if (frame.get() == NULL)
1273 { 1287 {
1274 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 1288 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
1275 } 1289 }
1303 Orthanc::ImageProcessing::Convert(*converted, *frame); 1317 Orthanc::ImageProcessing::Convert(*converted, *frame);
1304 Orthanc::ImageProcessing::ShiftScale2(*converted, b, a, false); 1318 Orthanc::ImageProcessing::ShiftScale2(*converted, b, a, false);
1305 } 1319 }
1306 1320
1307 assert(converted.get() != NULL); 1321 assert(converted.get() != NULL);
1308 GetViewport().RenderCurrentSceneFromCommand(*converted, sopInstanceUid_, frameNumber_, DisplayedFrameQuality_High); 1322 viewport.RenderCurrentSceneFromCommand(*converted, sopInstanceUid, frameNumber, DisplayedFrameQuality_High);
1309 GetViewport().cache_->Acquire(sopInstanceUid_, frameNumber_, converted.release(), QUALITY_FULL); 1323 viewport.cache_->Acquire(sopInstanceUid, frameNumber, converted.release(), QUALITY_FULL);
1310
1311 if (isPrefetch_)
1312 {
1313 GetViewport().ScheduleNextPrefetch();
1314 }
1315 } 1324 }
1316 }; 1325 };
1317 1326
1318 1327
1319 class PrefetchItem 1328 class PrefetchItem
1341 } 1350 }
1342 }; 1351 };
1343 1352
1344 1353
1345 std::unique_ptr<IObserver> observer_; 1354 std::unique_ptr<IObserver> observer_;
1346 OrthancStone::ILoadersContext& context_; 1355 OrthancStone::WebAssemblyLoadersContext& context_;
1347 boost::shared_ptr<OrthancStone::WebAssemblyViewport> viewport_; 1356 boost::shared_ptr<OrthancStone::WebAssemblyViewport> viewport_;
1348 boost::shared_ptr<OrthancStone::DicomResourcesLoader> loader_; 1357 boost::shared_ptr<OrthancStone::DicomResourcesLoader> loader_;
1349 OrthancStone::DicomSource source_; 1358 OrthancStone::DicomSource source_;
1350 boost::shared_ptr<FramesCache> cache_; 1359 boost::shared_ptr<FramesCache> cache_;
1351 std::unique_ptr<OrthancStone::SortedFrames> frames_; 1360 std::unique_ptr<OrthancStone::SortedFrames> frames_;
1651 else if (frames_.get() != NULL) 1660 else if (frames_.get() != NULL)
1652 { 1661 {
1653 const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(cursorIndex); 1662 const OrthancStone::DicomInstanceParameters& instance = frames_->GetInstanceOfFrame(cursorIndex);
1654 unsigned int frameNumber = frames_->GetFrameNumberInInstance(cursorIndex); 1663 unsigned int frameNumber = frames_->GetFrameNumberInInstance(cursorIndex);
1655 1664
1665 /**
1666 * If the full-resolution DICOM file is already available in the
1667 * cache of the oracle, skip the loading of the "rendered".
1668 **/
1669 std::unique_ptr<OrthancStone::WebAssemblyOracle::CachedInstanceAccessor> accessor(
1670 context_.AccessCachedInstance(instance.GetSopInstanceUid()));
1671
1672 if (accessor.get() != NULL &&
1673 accessor->IsValid())
1674 {
1675 try
1676 {
1677 SetFullDicomFrame::Apply(*this, accessor->GetDicom(), instance.GetSopInstanceUid(), frameNumber);
1678 return;
1679 }
1680 catch (Orthanc::OrthancException&)
1681 {
1682 // This happens in the case of a JPEG2k image unsupported by DCMTK
1683 }
1684 }
1685
1656 bool isMonochrome1 = (instance.GetImageInformation().GetPhotometricInterpretation() == 1686 bool isMonochrome1 = (instance.GetImageInformation().GetPhotometricInterpretation() ==
1657 Orthanc::PhotometricInterpretation_Monochrome1); 1687 Orthanc::PhotometricInterpretation_Monochrome1);
1658 1688
1659 const std::string uri = ("studies/" + frames_->GetStudyInstanceUid() + 1689 const std::string uri = ("studies/" + frames_->GetStudyInstanceUid() +
1660 "/series/" + frames_->GetSeriesInstanceUid() + 1690 "/series/" + frames_->GetSeriesInstanceUid() +
1705 lock->Invalidate(); 1735 lock->Invalidate();
1706 } 1736 }
1707 } 1737 }
1708 1738
1709 1739
1710 ViewerViewport(OrthancStone::ILoadersContext& context, 1740 ViewerViewport(OrthancStone::WebAssemblyLoadersContext& context,
1711 const OrthancStone::DicomSource& source, 1741 const OrthancStone::DicomSource& source,
1712 const std::string& canvas, 1742 const std::string& canvas,
1713 boost::shared_ptr<FramesCache> cache, 1743 boost::shared_ptr<FramesCache> cache,
1714 bool softwareRendering) : 1744 bool softwareRendering) :
1715 context_(context), 1745 context_(context),
1812 emscripten_set_wheel_callback(viewport_->GetCanvasCssSelector().c_str(), this, true, NULL); 1842 emscripten_set_wheel_callback(viewport_->GetCanvasCssSelector().c_str(), this, true, NULL);
1813 emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, this, false, NULL); 1843 emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, this, false, NULL);
1814 emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, this, false, NULL); 1844 emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, this, false, NULL);
1815 } 1845 }
1816 1846
1817 static boost::shared_ptr<ViewerViewport> Create(OrthancStone::ILoadersContext::ILock& lock, 1847 static boost::shared_ptr<ViewerViewport> Create(OrthancStone::WebAssemblyLoadersContext& context,
1818 const OrthancStone::DicomSource& source, 1848 const OrthancStone::DicomSource& source,
1819 const std::string& canvas, 1849 const std::string& canvas,
1820 boost::shared_ptr<FramesCache> cache, 1850 boost::shared_ptr<FramesCache> cache,
1821 bool softwareRendering) 1851 bool softwareRendering)
1822 { 1852 {
1823 boost::shared_ptr<ViewerViewport> viewport( 1853 boost::shared_ptr<ViewerViewport> viewport(
1824 new ViewerViewport(lock.GetContext(), source, canvas, cache, softwareRendering)); 1854 new ViewerViewport(context, source, canvas, cache, softwareRendering));
1825 1855
1826 viewport->loader_ = OrthancStone::DicomResourcesLoader::Create(lock); 1856 {
1827 viewport->Register<OrthancStone::DicomResourcesLoader::SuccessMessage>( 1857 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context.Lock());
1828 *viewport->loader_, &ViewerViewport::Handle); 1858
1829 1859 viewport->loader_ = OrthancStone::DicomResourcesLoader::Create(*lock);
1830 viewport->Register<OrthancStone::HttpCommand::SuccessMessage>( 1860 viewport->Register<OrthancStone::DicomResourcesLoader::SuccessMessage>(
1831 lock.GetOracleObservable(), &ViewerViewport::Handle); 1861 *viewport->loader_, &ViewerViewport::Handle);
1832 1862
1833 viewport->Register<OrthancStone::ParseDicomSuccessMessage>( 1863 viewport->Register<OrthancStone::HttpCommand::SuccessMessage>(
1834 lock.GetOracleObservable(), &ViewerViewport::Handle); 1864 lock->GetOracleObservable(), &ViewerViewport::Handle);
1865
1866 viewport->Register<OrthancStone::ParseDicomSuccessMessage>(
1867 lock->GetOracleObservable(), &ViewerViewport::Handle);
1868 }
1835 1869
1836 return viewport; 1870 return viewport;
1837 } 1871 }
1838 1872
1839 void SetFrames(OrthancStone::SortedFrames* frames) 1873 void SetFrames(OrthancStone::SortedFrames* frames)
2480 static boost::shared_ptr<ViewerViewport> GetViewport(const std::string& canvas) 2514 static boost::shared_ptr<ViewerViewport> GetViewport(const std::string& canvas)
2481 { 2515 {
2482 Viewports::iterator found = allViewports_.find(canvas); 2516 Viewports::iterator found = allViewports_.find(canvas);
2483 if (found == allViewports_.end()) 2517 if (found == allViewports_.end())
2484 { 2518 {
2485 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context_->Lock());
2486 boost::shared_ptr<ViewerViewport> viewport( 2519 boost::shared_ptr<ViewerViewport> viewport(
2487 ViewerViewport::Create(*lock, source_, canvas, cache_, softwareRendering_)); 2520 ViewerViewport::Create(*context_, source_, canvas, cache_, softwareRendering_));
2488 viewport->SetMouseButtonActions(leftButtonAction_, middleButtonAction_, rightButtonAction_); 2521 viewport->SetMouseButtonActions(leftButtonAction_, middleButtonAction_, rightButtonAction_);
2489 viewport->AcquireObserver(new WebAssemblyObserver); 2522 viewport->AcquireObserver(new WebAssemblyObserver);
2490 viewport->SetAnnotations(annotations_); 2523 viewport->SetAnnotations(annotations_);
2491 allViewports_[canvas] = viewport; 2524 allViewports_[canvas] = viewport;
2492 return viewport; 2525 return viewport;