changeset 1642:5cc589bfb385

lazy computation of DicomInstanceParameters::GetImageInformation()
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 10 Nov 2020 17:21:23 +0100
parents df4fd96c5706
children 882e2253a90e
files OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp OrthancStone/Sources/Toolbox/DicomInstanceParameters.h OrthancStone/Sources/Toolbox/SlicesSorter.h
diffstat 3 files changed, 59 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp	Tue Nov 10 16:58:27 2020 +0100
+++ b/OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp	Tue Nov 10 17:21:23 2020 +0100
@@ -68,8 +68,7 @@
   }
 
 
-  DicomInstanceParameters::Data::Data(const Orthanc::DicomMap& dicom) :
-    imageInformation_(dicom)
+  DicomInstanceParameters::Data::Data(const Orthanc::DicomMap& dicom)
   {
     if (!dicom.LookupStringValue(studyInstanceUid_, Orthanc::DICOM_TAG_STUDY_INSTANCE_UID, false) ||
         !dicom.LookupStringValue(seriesInstanceUid_, Orthanc::DICOM_TAG_SERIES_INSTANCE_UID, false) ||
@@ -206,6 +205,25 @@
   }
 
 
+  const Orthanc::DicomImageInformation& DicomInstanceParameters::GetImageInformation() const
+  {
+    assert(tags_.get() != NULL);
+    
+    if (imageInformation_.get() == NULL)
+    {
+      const_cast<DicomInstanceParameters&>(*this).imageInformation_.
+        reset(new Orthanc::DicomImageInformation(GetTags()));
+
+      assert(imageInformation_->GetWidth() == GetWidth());
+      assert(imageInformation_->GetHeight() == GetHeight());
+      assert(imageInformation_->GetNumberOfFrames() == GetNumberOfFrames());
+    }
+
+    assert(imageInformation_.get() != NULL);
+    return *imageInformation_;
+  }
+  
+
   CoordinateSystem3D  DicomInstanceParameters::GetFrameGeometry(unsigned int frame) const
   {
     if (frame >= data_.numberOfFrames_)
@@ -253,7 +271,7 @@
   bool DicomInstanceParameters::IsColor() const
   {
     Orthanc::PhotometricInterpretation photometric =
-      data_.imageInformation_.GetPhotometricInterpretation();
+      GetImageInformation().GetPhotometricInterpretation();
     
     return (photometric != Orthanc::PhotometricInterpretation_Monochrome1 &&
             photometric != Orthanc::PhotometricInterpretation_Monochrome2);
@@ -465,7 +483,7 @@
                                     data_.defaultWindowingWidth_);
       }
       
-      switch (data_.imageInformation_.GetPhotometricInterpretation())
+      switch (GetImageInformation().GetPhotometricInterpretation())
       {
         case Orthanc::PhotometricInterpretation_Monochrome1:
           texture->SetInverted(true);
--- a/OrthancStone/Sources/Toolbox/DicomInstanceParameters.h	Tue Nov 10 16:58:27 2020 +0100
+++ b/OrthancStone/Sources/Toolbox/DicomInstanceParameters.h	Tue Nov 10 17:21:23 2020 +0100
@@ -22,8 +22,8 @@
 
 #pragma once
 
+#include "../Scene2D/LookupTableTextureSceneLayer.h"
 #include "../StoneEnumerations.h"
-#include "../Scene2D/LookupTableTextureSceneLayer.h"
 #include "../Toolbox/CoordinateSystem3D.h"
 
 #include <IDynamicObject.h>
@@ -39,48 +39,51 @@
   private:
     struct Data   // Plain old struct to ease the copy constructor
     {
-      std::string                       orthancInstanceId_;
-      std::string                       studyInstanceUid_;
-      std::string                       seriesInstanceUid_;
-      std::string                       sopInstanceUid_;
-      Orthanc::DicomImageInformation    imageInformation_;  // TODO REMOVE
-      SopClassUid                       sopClassUid_;
-      unsigned int                      numberOfFrames_;
-      unsigned int                      width_;
-      unsigned int                      height_;
-      double                            sliceThickness_;
-      double                            pixelSpacingX_;
-      double                            pixelSpacingY_;
-      CoordinateSystem3D                geometry_;
-      Vector                            frameOffsets_;
-      bool                              hasRescale_;
-      double                            rescaleIntercept_;
-      double                            rescaleSlope_;
-      bool                              hasDefaultWindowing_;
-      float                             defaultWindowingCenter_;
-      float                             defaultWindowingWidth_;
-      bool                              hasIndexInSeries_;
-      unsigned int                      indexInSeries_;
-      std::string                       doseUnits_;
-      double                            doseGridScaling_;
+      std::string         orthancInstanceId_;
+      std::string         studyInstanceUid_;
+      std::string         seriesInstanceUid_;
+      std::string         sopInstanceUid_;
+      SopClassUid         sopClassUid_;
+      unsigned int        numberOfFrames_;
+      unsigned int        width_;
+      unsigned int        height_;
+      double              sliceThickness_;
+      double              pixelSpacingX_;
+      double              pixelSpacingY_;
+      CoordinateSystem3D  geometry_;
+      Vector              frameOffsets_;
+      bool                hasRescale_;
+      double              rescaleIntercept_;
+      double              rescaleSlope_;
+      bool                hasDefaultWindowing_;
+      float               defaultWindowingCenter_;
+      float               defaultWindowingWidth_;
+      bool                hasIndexInSeries_;
+      unsigned int        indexInSeries_;
+      std::string         doseUnits_;
+      double              doseGridScaling_;
 
       explicit Data(const Orthanc::DicomMap& dicom);
     };
 
     
-    Data  data_;
+    Data                                             data_;
+    std::unique_ptr<Orthanc::DicomMap>               tags_;
+    std::unique_ptr<Orthanc::DicomImageInformation>  imageInformation_;  // Lazy evaluation
 
     void ApplyRescaleAndDoseScaling(Orthanc::ImageAccessor& image,
                                     bool useDouble) const;
 
   public:
     explicit DicomInstanceParameters(const DicomInstanceParameters& other) :
-      data_(other.data_)
+      data_(other.data_),
+      tags_(other.tags_->Clone())
     {
     }
 
     explicit DicomInstanceParameters(const Orthanc::DicomMap& dicom) :
-      data_(dicom)
+      data_(dicom),
+      tags_(dicom.Clone())
     {
     }
 
@@ -99,9 +102,9 @@
       return data_.orthancInstanceId_;
     }
 
-    const Orthanc::DicomImageInformation& GetImageInformation() const
+    const Orthanc::DicomMap& GetTags() const
     {
-      return data_.imageInformation_;
+      return *tags_;
     }
 
     const std::string& GetStudyInstanceUid() const
@@ -159,6 +162,9 @@
       return data_.geometry_;
     }
 
+    // WARNING - Calling this method can throw exception
+    const Orthanc::DicomImageInformation& GetImageInformation() const;
+
     CoordinateSystem3D GetFrameGeometry(unsigned int frame) const;
 
     bool IsPlaneWithinSlice(unsigned int frame,
--- a/OrthancStone/Sources/Toolbox/SlicesSorter.h	Tue Nov 10 16:58:27 2020 +0100
+++ b/OrthancStone/Sources/Toolbox/SlicesSorter.h	Tue Nov 10 17:21:23 2020 +0100
@@ -28,7 +28,7 @@
 
 namespace OrthancStone
 {
-  // TODO - Rename this as "PlanesSorter"
+  // TODO - Replace this with "SortedFrames"
   class SlicesSorter : public boost::noncopyable
   {
   private: