# HG changeset patch # User Sebastien Jodogne # Date 1745600542 -7200 # Node ID 2161277b4586ec3c321cb326c74aa397b1852842 # Parent cbad54feb881aa9b571acfa7bfc0625ce74685a9 experimental support for textual DICOM SR diff -r cbad54feb881 -r 2161277b4586 Applications/StoneWebViewer/NEWS --- a/Applications/StoneWebViewer/NEWS Fri Apr 25 17:50:05 2025 +0200 +++ b/Applications/StoneWebViewer/NEWS Fri Apr 25 19:02:22 2025 +0200 @@ -1,6 +1,7 @@ Pending changes in the mainline =============================== +* Experimental support for DICOM SR, display of textual reports * Experimental support for DICOM SR "Measurement Report" (TID 1500 - only polylines) * Added "Print" and "Download" buttons in the PDF viewer toolbar * New configuration option "ScreenshotTemplate" to define the filename diff -r cbad54feb881 -r 2161277b4586 Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp --- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Fri Apr 25 17:50:05 2025 +0200 +++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp Fri Apr 25 19:02:22 2025 +0200 @@ -377,6 +377,7 @@ }; std::unique_ptr sr_; + OrthancStone::DicomInstanceParameters parameters_; std::vector frames_; void Finalize() @@ -414,7 +415,8 @@ public: DicomStructuredReportFrames(const OrthancStone::DicomStructuredReport& sr, const OrthancStone::LoadedDicomResources& instances) : - sr_(new OrthancStone::DicomStructuredReport(sr)) + sr_(new OrthancStone::DicomStructuredReport(sr)), + parameters_(sr.GetMainDicomTags()) { std::list tmp; sr_->ExportReferencedFrames(tmp); @@ -448,23 +450,44 @@ virtual size_t GetFramesCount() const ORTHANC_OVERRIDE { - return frames_.size(); + return frames_.size() + 1; } virtual const OrthancStone::DicomInstanceParameters& GetInstanceOfFrame(size_t frameIndex) const ORTHANC_OVERRIDE { - return GetFrame(frameIndex).GetParameters(); + if (frameIndex == frames_.size()) + { + return parameters_; + } + else + { + return GetFrame(frameIndex).GetParameters(); + } } virtual unsigned int GetFrameNumberInInstance(size_t frameIndex) const ORTHANC_OVERRIDE { - return GetFrame(frameIndex).GetInformation().GetFrameNumber(); + if (frameIndex == frames_.size()) + { + return 0; + } + else + { + return GetFrame(frameIndex).GetInformation().GetFrameNumber(); + } } virtual bool LookupFrame(size_t& frameIndex, const std::string& sopInstanceUid, unsigned int frameNumber) const ORTHANC_OVERRIDE { + if (sopInstanceUid == sr_->GetSopInstanceUid() && + frameNumber == 0) + { + frameIndex = frames_.size(); + return true; + } + // TODO - Could be speeded up with an additional index for (size_t i = 0; i < frames_.size(); i++) { @@ -2692,6 +2715,10 @@ std::list layerSources_; + // TODO - Share this with the compositor? + OrthancStone::FontRenderer font_; + + void UpdateWindowing(WindowingState state, const OrthancStone::Windowing& windowing) { @@ -2832,8 +2859,12 @@ * (cf. LSD-479). **/ - bool isMonochrome1 = (instance.GetImageInformation().GetPhotometricInterpretation() == - Orthanc::PhotometricInterpretation_Monochrome1); + bool isMonochrome1 = false; + if (instance.GetSopClassUid() != OrthancStone::SopClassUid_ComprehensiveSR) + { + isMonochrome1 = (instance.GetImageInformation().GetPhotometricInterpretation() == + Orthanc::PhotometricInterpretation_Monochrome1); + } std::unique_ptr layer; @@ -3116,7 +3147,17 @@ { try { - std::unique_ptr frame(accessor->GetDicom().DecodeFrame(frameNumber)); + std::unique_ptr frame; + if (instance.GetSopClassUid() == OrthancStone::SopClassUid_ComprehensiveSR) + { + OrthancStone::DicomStructuredReport report(const_cast(accessor->GetDicom())); + frame.reset(report.Render(font_, OrthancStone::Color(255, 0, 0), OrthancStone::Color(0, 255, 0))); + } + else + { + frame.reset(accessor->GetDicom().DecodeFrame(frameNumber)); + } + SetFullDicomFrame::Apply(*this, accessor->GetDicom(), frame.release(), instance.GetSopInstanceUid(), frameNumber); return; // Success } @@ -3220,6 +3261,7 @@ std::string ttf; Orthanc::EmbeddedResources::GetFileResource(ttf, Orthanc::EmbeddedResources::UBUNTU_FONT); lock->GetCompositor().SetFont(0, ttf, 16 /* font size */, Orthanc::Encoding_Latin1); + font_.LoadFont(ttf, 16 /* font size */); } emscripten_set_wheel_callback(viewport_->GetCanvasCssSelector().c_str(), this, true, OnWheel); diff -r cbad54feb881 -r 2161277b4586 OrthancStone/Sources/Toolbox/DicomStructuredReport.cpp --- a/OrthancStone/Sources/Toolbox/DicomStructuredReport.cpp Fri Apr 25 17:50:05 2025 +0200 +++ b/OrthancStone/Sources/Toolbox/DicomStructuredReport.cpp Fri Apr 25 19:02:22 2025 +0200 @@ -641,6 +641,7 @@ StoneToolbox::ExtractMainDicomTags(mainDicomTags_, dicom); StoneToolbox::CopyDicomTag(mainDicomTags_, dicom, Orthanc::DicomTag(0x0040, 0xa491)); // "Completion Flag" StoneToolbox::CopyDicomTag(mainDicomTags_, dicom, Orthanc::DicomTag(0x0040, 0xa493)); // "Verification Flag" + StoneToolbox::CopyDicomTag(mainDicomTags_, dicom, Orthanc::DICOM_TAG_SOP_CLASS_UID); DcmDataset& dataset = *dicom.GetDcmtkObject().getDataset();