Mercurial > hg > orthanc-stone
diff Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp @ 1657:66e5fcdf5597
pdf viewer is working
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 18 Nov 2020 11:19:09 +0100 |
parents | 39137da83b0b |
children | fc883105ee11 |
line wrap: on
line diff
--- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Tue Nov 17 11:18:53 2020 +0100 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Wed Nov 18 11:19:09 2020 +0100 @@ -184,9 +184,14 @@ virtual void SignalSeriesMetadataLoaded(const std::string& studyInstanceUid, const std::string& seriesInstanceUid) = 0; + + virtual void SignalSeriesPdfLoaded(const std::string& studyInstanceUid, + const std::string& seriesInstanceUid, + const std::string& pdf) = 0; }; private: + OrthancStone::ILoadersContext& context_; std::unique_ptr<IObserver> observer_; OrthancStone::DicomSource source_; size_t pending_; @@ -196,7 +201,9 @@ boost::shared_ptr<OrthancStone::SeriesThumbnailsLoader> thumbnailsLoader_; boost::shared_ptr<OrthancStone::SeriesMetadataLoader> metadataLoader_; - explicit ResourcesLoader(const OrthancStone::DicomSource& source) : + explicit ResourcesLoader(OrthancStone::ILoadersContext& context, + const OrthancStone::DicomSource& source) : + context_(context), source_(source), pending_(0), studies_(new OrthancStone::LoadedDicomResources(Orthanc::DICOM_TAG_STUDY_INSTANCE_UID)), @@ -292,11 +299,56 @@ pending_ += 2; } + + class PdfInfo : public Orthanc::IDynamicObject + { + private: + std::string studyInstanceUid_; + std::string seriesInstanceUid_; + + public: + PdfInfo(const std::string& studyInstanceUid, + const std::string& seriesInstanceUid) : + studyInstanceUid_(studyInstanceUid), + seriesInstanceUid_(seriesInstanceUid) + { + } + + const std::string& GetStudyInstanceUid() const + { + return studyInstanceUid_; + } + + const std::string& GetSeriesInstanceUid() const + { + return seriesInstanceUid_; + } + }; + + + void Handle(const OrthancStone::ParseDicomSuccessMessage& message) + { + const PdfInfo& info = dynamic_cast<const PdfInfo&>(message.GetOrigin().GetPayload()); + + if (observer_.get() != NULL) + { + std::string pdf; + if (message.GetDicom().ExtractPdf(pdf)) + { + observer_->SignalSeriesPdfLoaded(info.GetStudyInstanceUid(), info.GetSeriesInstanceUid(), pdf); + } + else + { + LOG(ERROR) << "Unable to extract PDF from series: " << info.GetSeriesInstanceUid(); + } + } + } + public: static boost::shared_ptr<ResourcesLoader> Create(OrthancStone::ILoadersContext::ILock& lock, const OrthancStone::DicomSource& source) { - boost::shared_ptr<ResourcesLoader> loader(new ResourcesLoader(source)); + boost::shared_ptr<ResourcesLoader> loader(new ResourcesLoader(lock.GetContext(), source)); loader->resourcesLoader_ = OrthancStone::DicomResourcesLoader::Create(lock); loader->thumbnailsLoader_ = OrthancStone::SeriesThumbnailsLoader::Create(lock, PRIORITY_LOW); @@ -310,6 +362,9 @@ loader->Register<OrthancStone::SeriesMetadataLoader::SuccessMessage>( *loader->metadataLoader_, &ResourcesLoader::Handle); + + loader->Register<OrthancStone::ParseDicomSuccessMessage>( + lock.GetOracleObservable(), &ResourcesLoader::Handle); return loader; } @@ -408,6 +463,41 @@ { observer_.reset(observer); } + + void FetchPdf(const std::string& studyInstanceUid, + const std::string& seriesInstanceUid) + { + OrthancStone::SeriesMetadataLoader::Accessor accessor(*metadataLoader_, seriesInstanceUid); + + if (accessor.IsComplete()) + { + if (accessor.GetInstancesCount() > 1) + { + LOG(INFO) << "Series with more than one instance, will show the first PDF: " + << seriesInstanceUid; + } + + for (size_t i = 0; i < accessor.GetInstancesCount(); i++) + { + std::string sopClassUid, sopInstanceUid; + if (accessor.GetInstance(i).LookupStringValue(sopClassUid, Orthanc::DICOM_TAG_SOP_CLASS_UID, false) && + accessor.GetInstance(i).LookupStringValue(sopInstanceUid, Orthanc::DICOM_TAG_SOP_INSTANCE_UID, false) && + sopClassUid == "1.2.840.10008.5.1.4.1.1.104.1") + { + std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context_.Lock()); + lock->Schedule( + GetSharedObserver(), PRIORITY_NORMAL, OrthancStone::ParseDicomFromWadoCommand::Create( + source_, studyInstanceUid, seriesInstanceUid, sopInstanceUid, + false /* no transcoding */, Orthanc::DicomTransferSyntax_LittleEndianExplicit /* dummy value */, + new PdfInfo(studyInstanceUid, seriesInstanceUid))); + + return; + } + } + + LOG(WARNING) << "Series without a PDF: " << seriesInstanceUid; + } + } }; @@ -2229,7 +2319,6 @@ static_cast<int>(countFrames), quality); - UpdateReferenceLines(); } @@ -2241,6 +2330,25 @@ it->second->FocusOnPoint(click); } } + + virtual void SignalSeriesPdfLoaded(const std::string& studyInstanceUid, + const std::string& seriesInstanceUid, + const std::string& pdf) ORTHANC_OVERRIDE + { + EM_ASM({ + const customEvent = document.createEvent("CustomEvent"); + customEvent.initCustomEvent("PdfLoaded", false, false, + { "studyInstanceUid" : UTF8ToString($0), + "seriesInstanceUid" : UTF8ToString($1), + "pdfPointer" : $2, + "pdfSize": $3}); + window.dispatchEvent(customEvent); + }, + studyInstanceUid.c_str(), + seriesInstanceUid.c_str(), + pdf.empty() ? 0 : reinterpret_cast<intptr_t>(pdf.c_str()), // Explicit conversion to an integer + pdf.size()); + } }; @@ -2746,4 +2854,17 @@ } EXTERN_CATCH_EXCEPTIONS; } + + + EMSCRIPTEN_KEEPALIVE + void FetchPdf(const char* studyInstanceUid, + const char* seriesInstanceUid) + { + try + { + LOG(INFO) << "Fetching PDF series: " << seriesInstanceUid; + GetResourcesLoader().FetchPdf(studyInstanceUid, seriesInstanceUid); + } + EXTERN_CATCH_EXCEPTIONS; + } }