Mercurial > hg > orthanc-stone
comparison 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 |
comparison
equal
deleted
inserted
replaced
1656:4cdc297be5a6 | 1657:66e5fcdf5597 |
---|---|
182 virtual void SignalSeriesThumbnailLoaded(const std::string& studyInstanceUid, | 182 virtual void SignalSeriesThumbnailLoaded(const std::string& studyInstanceUid, |
183 const std::string& seriesInstanceUid) = 0; | 183 const std::string& seriesInstanceUid) = 0; |
184 | 184 |
185 virtual void SignalSeriesMetadataLoaded(const std::string& studyInstanceUid, | 185 virtual void SignalSeriesMetadataLoaded(const std::string& studyInstanceUid, |
186 const std::string& seriesInstanceUid) = 0; | 186 const std::string& seriesInstanceUid) = 0; |
187 | |
188 virtual void SignalSeriesPdfLoaded(const std::string& studyInstanceUid, | |
189 const std::string& seriesInstanceUid, | |
190 const std::string& pdf) = 0; | |
187 }; | 191 }; |
188 | 192 |
189 private: | 193 private: |
194 OrthancStone::ILoadersContext& context_; | |
190 std::unique_ptr<IObserver> observer_; | 195 std::unique_ptr<IObserver> observer_; |
191 OrthancStone::DicomSource source_; | 196 OrthancStone::DicomSource source_; |
192 size_t pending_; | 197 size_t pending_; |
193 boost::shared_ptr<OrthancStone::LoadedDicomResources> studies_; | 198 boost::shared_ptr<OrthancStone::LoadedDicomResources> studies_; |
194 boost::shared_ptr<OrthancStone::LoadedDicomResources> series_; | 199 boost::shared_ptr<OrthancStone::LoadedDicomResources> series_; |
195 boost::shared_ptr<OrthancStone::DicomResourcesLoader> resourcesLoader_; | 200 boost::shared_ptr<OrthancStone::DicomResourcesLoader> resourcesLoader_; |
196 boost::shared_ptr<OrthancStone::SeriesThumbnailsLoader> thumbnailsLoader_; | 201 boost::shared_ptr<OrthancStone::SeriesThumbnailsLoader> thumbnailsLoader_; |
197 boost::shared_ptr<OrthancStone::SeriesMetadataLoader> metadataLoader_; | 202 boost::shared_ptr<OrthancStone::SeriesMetadataLoader> metadataLoader_; |
198 | 203 |
199 explicit ResourcesLoader(const OrthancStone::DicomSource& source) : | 204 explicit ResourcesLoader(OrthancStone::ILoadersContext& context, |
205 const OrthancStone::DicomSource& source) : | |
206 context_(context), | |
200 source_(source), | 207 source_(source), |
201 pending_(0), | 208 pending_(0), |
202 studies_(new OrthancStone::LoadedDicomResources(Orthanc::DICOM_TAG_STUDY_INSTANCE_UID)), | 209 studies_(new OrthancStone::LoadedDicomResources(Orthanc::DICOM_TAG_STUDY_INSTANCE_UID)), |
203 series_(new OrthancStone::LoadedDicomResources(Orthanc::DICOM_TAG_SERIES_INSTANCE_UID)) | 210 series_(new OrthancStone::LoadedDicomResources(Orthanc::DICOM_TAG_SERIES_INSTANCE_UID)) |
204 { | 211 { |
290 new Orthanc::SingleValueObject<Orthanc::ResourceType>(Orthanc::ResourceType_Series)); | 297 new Orthanc::SingleValueObject<Orthanc::ResourceType>(Orthanc::ResourceType_Series)); |
291 | 298 |
292 pending_ += 2; | 299 pending_ += 2; |
293 } | 300 } |
294 | 301 |
302 | |
303 class PdfInfo : public Orthanc::IDynamicObject | |
304 { | |
305 private: | |
306 std::string studyInstanceUid_; | |
307 std::string seriesInstanceUid_; | |
308 | |
309 public: | |
310 PdfInfo(const std::string& studyInstanceUid, | |
311 const std::string& seriesInstanceUid) : | |
312 studyInstanceUid_(studyInstanceUid), | |
313 seriesInstanceUid_(seriesInstanceUid) | |
314 { | |
315 } | |
316 | |
317 const std::string& GetStudyInstanceUid() const | |
318 { | |
319 return studyInstanceUid_; | |
320 } | |
321 | |
322 const std::string& GetSeriesInstanceUid() const | |
323 { | |
324 return seriesInstanceUid_; | |
325 } | |
326 }; | |
327 | |
328 | |
329 void Handle(const OrthancStone::ParseDicomSuccessMessage& message) | |
330 { | |
331 const PdfInfo& info = dynamic_cast<const PdfInfo&>(message.GetOrigin().GetPayload()); | |
332 | |
333 if (observer_.get() != NULL) | |
334 { | |
335 std::string pdf; | |
336 if (message.GetDicom().ExtractPdf(pdf)) | |
337 { | |
338 observer_->SignalSeriesPdfLoaded(info.GetStudyInstanceUid(), info.GetSeriesInstanceUid(), pdf); | |
339 } | |
340 else | |
341 { | |
342 LOG(ERROR) << "Unable to extract PDF from series: " << info.GetSeriesInstanceUid(); | |
343 } | |
344 } | |
345 } | |
346 | |
295 public: | 347 public: |
296 static boost::shared_ptr<ResourcesLoader> Create(OrthancStone::ILoadersContext::ILock& lock, | 348 static boost::shared_ptr<ResourcesLoader> Create(OrthancStone::ILoadersContext::ILock& lock, |
297 const OrthancStone::DicomSource& source) | 349 const OrthancStone::DicomSource& source) |
298 { | 350 { |
299 boost::shared_ptr<ResourcesLoader> loader(new ResourcesLoader(source)); | 351 boost::shared_ptr<ResourcesLoader> loader(new ResourcesLoader(lock.GetContext(), source)); |
300 | 352 |
301 loader->resourcesLoader_ = OrthancStone::DicomResourcesLoader::Create(lock); | 353 loader->resourcesLoader_ = OrthancStone::DicomResourcesLoader::Create(lock); |
302 loader->thumbnailsLoader_ = OrthancStone::SeriesThumbnailsLoader::Create(lock, PRIORITY_LOW); | 354 loader->thumbnailsLoader_ = OrthancStone::SeriesThumbnailsLoader::Create(lock, PRIORITY_LOW); |
303 loader->metadataLoader_ = OrthancStone::SeriesMetadataLoader::Create(lock); | 355 loader->metadataLoader_ = OrthancStone::SeriesMetadataLoader::Create(lock); |
304 | 356 |
308 loader->Register<OrthancStone::SeriesThumbnailsLoader::SuccessMessage>( | 360 loader->Register<OrthancStone::SeriesThumbnailsLoader::SuccessMessage>( |
309 *loader->thumbnailsLoader_, &ResourcesLoader::Handle); | 361 *loader->thumbnailsLoader_, &ResourcesLoader::Handle); |
310 | 362 |
311 loader->Register<OrthancStone::SeriesMetadataLoader::SuccessMessage>( | 363 loader->Register<OrthancStone::SeriesMetadataLoader::SuccessMessage>( |
312 *loader->metadataLoader_, &ResourcesLoader::Handle); | 364 *loader->metadataLoader_, &ResourcesLoader::Handle); |
365 | |
366 loader->Register<OrthancStone::ParseDicomSuccessMessage>( | |
367 lock.GetOracleObservable(), &ResourcesLoader::Handle); | |
313 | 368 |
314 return loader; | 369 return loader; |
315 } | 370 } |
316 | 371 |
317 void FetchAllStudies() | 372 void FetchAllStudies() |
405 } | 460 } |
406 | 461 |
407 void AcquireObserver(IObserver* observer) | 462 void AcquireObserver(IObserver* observer) |
408 { | 463 { |
409 observer_.reset(observer); | 464 observer_.reset(observer); |
465 } | |
466 | |
467 void FetchPdf(const std::string& studyInstanceUid, | |
468 const std::string& seriesInstanceUid) | |
469 { | |
470 OrthancStone::SeriesMetadataLoader::Accessor accessor(*metadataLoader_, seriesInstanceUid); | |
471 | |
472 if (accessor.IsComplete()) | |
473 { | |
474 if (accessor.GetInstancesCount() > 1) | |
475 { | |
476 LOG(INFO) << "Series with more than one instance, will show the first PDF: " | |
477 << seriesInstanceUid; | |
478 } | |
479 | |
480 for (size_t i = 0; i < accessor.GetInstancesCount(); i++) | |
481 { | |
482 std::string sopClassUid, sopInstanceUid; | |
483 if (accessor.GetInstance(i).LookupStringValue(sopClassUid, Orthanc::DICOM_TAG_SOP_CLASS_UID, false) && | |
484 accessor.GetInstance(i).LookupStringValue(sopInstanceUid, Orthanc::DICOM_TAG_SOP_INSTANCE_UID, false) && | |
485 sopClassUid == "1.2.840.10008.5.1.4.1.1.104.1") | |
486 { | |
487 std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context_.Lock()); | |
488 lock->Schedule( | |
489 GetSharedObserver(), PRIORITY_NORMAL, OrthancStone::ParseDicomFromWadoCommand::Create( | |
490 source_, studyInstanceUid, seriesInstanceUid, sopInstanceUid, | |
491 false /* no transcoding */, Orthanc::DicomTransferSyntax_LittleEndianExplicit /* dummy value */, | |
492 new PdfInfo(studyInstanceUid, seriesInstanceUid))); | |
493 | |
494 return; | |
495 } | |
496 } | |
497 | |
498 LOG(WARNING) << "Series without a PDF: " << seriesInstanceUid; | |
499 } | |
410 } | 500 } |
411 }; | 501 }; |
412 | 502 |
413 | 503 |
414 | 504 |
2227 viewport.GetCanvasId().c_str(), | 2317 viewport.GetCanvasId().c_str(), |
2228 static_cast<int>(currentFrame), | 2318 static_cast<int>(currentFrame), |
2229 static_cast<int>(countFrames), | 2319 static_cast<int>(countFrames), |
2230 quality); | 2320 quality); |
2231 | 2321 |
2232 | |
2233 UpdateReferenceLines(); | 2322 UpdateReferenceLines(); |
2234 } | 2323 } |
2235 | 2324 |
2236 virtual void SignalCrosshair(const OrthancStone::Vector& click) ORTHANC_OVERRIDE | 2325 virtual void SignalCrosshair(const OrthancStone::Vector& click) ORTHANC_OVERRIDE |
2237 { | 2326 { |
2238 for (Viewports::const_iterator it = allViewports_.begin(); it != allViewports_.end(); ++it) | 2327 for (Viewports::const_iterator it = allViewports_.begin(); it != allViewports_.end(); ++it) |
2239 { | 2328 { |
2240 assert(it->second != NULL); | 2329 assert(it->second != NULL); |
2241 it->second->FocusOnPoint(click); | 2330 it->second->FocusOnPoint(click); |
2242 } | 2331 } |
2332 } | |
2333 | |
2334 virtual void SignalSeriesPdfLoaded(const std::string& studyInstanceUid, | |
2335 const std::string& seriesInstanceUid, | |
2336 const std::string& pdf) ORTHANC_OVERRIDE | |
2337 { | |
2338 EM_ASM({ | |
2339 const customEvent = document.createEvent("CustomEvent"); | |
2340 customEvent.initCustomEvent("PdfLoaded", false, false, | |
2341 { "studyInstanceUid" : UTF8ToString($0), | |
2342 "seriesInstanceUid" : UTF8ToString($1), | |
2343 "pdfPointer" : $2, | |
2344 "pdfSize": $3}); | |
2345 window.dispatchEvent(customEvent); | |
2346 }, | |
2347 studyInstanceUid.c_str(), | |
2348 seriesInstanceUid.c_str(), | |
2349 pdf.empty() ? 0 : reinterpret_cast<intptr_t>(pdf.c_str()), // Explicit conversion to an integer | |
2350 pdf.size()); | |
2243 } | 2351 } |
2244 }; | 2352 }; |
2245 | 2353 |
2246 | 2354 |
2247 | 2355 |
2744 viewport->Redraw(); | 2852 viewport->Redraw(); |
2745 } | 2853 } |
2746 } | 2854 } |
2747 EXTERN_CATCH_EXCEPTIONS; | 2855 EXTERN_CATCH_EXCEPTIONS; |
2748 } | 2856 } |
2857 | |
2858 | |
2859 EMSCRIPTEN_KEEPALIVE | |
2860 void FetchPdf(const char* studyInstanceUid, | |
2861 const char* seriesInstanceUid) | |
2862 { | |
2863 try | |
2864 { | |
2865 LOG(INFO) << "Fetching PDF series: " << seriesInstanceUid; | |
2866 GetResourcesLoader().FetchPdf(studyInstanceUid, seriesInstanceUid); | |
2867 } | |
2868 EXTERN_CATCH_EXCEPTIONS; | |
2869 } | |
2749 } | 2870 } |