changeset 601:a30dd5ee45c6 annotations

integration mainline->annotations
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 07 Sep 2026 20:58:30 +0200
parents 06eec59e726b (current diff) 164565ec35c3 (diff)
children f72b20cbd84e 10b2ec6ca97f
files Framework/Inputs/DicomPyramid.cpp Framework/Inputs/DicomPyramid.h Framework/Inputs/DicomPyramidInstance.h Framework/Inputs/ITiledPyramid.h Framework/Inputs/OnTheFlyPyramid.h Framework/Inputs/TiledPyramidStatistics.h Framework/Outputs/InMemoryTiledImage.h ViewerPlugin/Plugin.cpp
diffstat 15 files changed, 114 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/Framework/Inputs/CytomineImage.h	Mon Sep 07 20:58:06 2026 +0200
+++ b/Framework/Inputs/CytomineImage.h	Mon Sep 07 20:58:30 2026 +0200
@@ -96,5 +96,10 @@
     {
       return 0;  // Image is stored on the remote Cytomine server
     }
+
+    virtual bool LookupObjectiveLensPower(float& power) const ORTHANC_OVERRIDE
+    {
+      return false;
+    }
   };
 }
--- a/Framework/Inputs/DicomPyramid.cpp	Mon Sep 07 20:58:06 2026 +0200
+++ b/Framework/Inputs/DicomPyramid.cpp	Mon Sep 07 20:58:30 2026 +0200
@@ -298,4 +298,33 @@
 
     return found;
   }
+
+
+  bool DicomPyramid::LookupObjectiveLensPower(float& power) const
+  {
+    bool found = false;
+
+    for (size_t i = 0; i < instances_.size(); i++)
+    {
+      assert(instances_[i] != NULL);
+
+      float tmp;
+      if (instances_[i]->IsLevel(0) &&  // Only consider the finest level
+          instances_[i]->LookupObjectiveLensPower(tmp))
+      {
+        if (!found)
+        {
+          found = true;
+          power = tmp;
+        }
+        else if (!ImageToolbox::IsNear(power, tmp))
+        {
+          LOG(WARNING) << "Inconsistency of objective lens power in series: " << seriesId_;
+          return false;
+        }
+      }
+    }
+
+    return found;
+  }
 }
--- a/Framework/Inputs/DicomPyramid.h	Mon Sep 07 20:58:06 2026 +0200
+++ b/Framework/Inputs/DicomPyramid.h	Mon Sep 07 20:58:30 2026 +0200
@@ -94,5 +94,7 @@
 
     bool LookupImagedVolumeSize(double& width,
                                 double& height) const;
+
+    virtual bool LookupObjectiveLensPower(float& power) const ORTHANC_OVERRIDE;
   };
 }
--- a/Framework/Inputs/DicomPyramidInstance.cpp	Mon Sep 07 20:58:06 2026 +0200
+++ b/Framework/Inputs/DicomPyramidInstance.cpp	Mon Sep 07 20:58:30 2026 +0200
@@ -56,6 +56,8 @@
   static const Orthanc::DicomTag DICOM_TAG_RECOMMENDED_ABSENT_PIXEL_CIELAB(0x0048, 0x0015);
   static const Orthanc::DicomTag DICOM_TAG_IMAGED_VOLUME_WIDTH(0x0048, 0x0001);
   static const Orthanc::DicomTag DICOM_TAG_IMAGED_VOLUME_HEIGHT(0x0048, 0x0002);
+  static const Orthanc::DicomTag DICOM_TAG_OPTICAL_PATH_SEQUENCE(0x0048, 0x0105);
+  static const Orthanc::DicomTag DICOM_TAG_OBJECTIVE_LENS_POWER(0x0048, 0x0112);
 
   static ImageCompression DetectImageCompression(OrthancStone::IOrthancConnection& orthanc,
                                                  const std::string& instanceId)
@@ -298,6 +300,20 @@
     hasImagedVolumeSize_ = (
       reader.GetDoubleValue(imagedVolumeWidth_, Orthanc::DicomPath(DICOM_TAG_IMAGED_VOLUME_WIDTH)) &&
       reader.GetDoubleValue(imagedVolumeHeight_, Orthanc::DicomPath(DICOM_TAG_IMAGED_VOLUME_HEIGHT)));
+
+    // New in WSI 4.0
+    size_t countOpticalPaths;
+    if (reader.GetDataset().GetSequenceSize(countOpticalPaths, Orthanc::DicomPath(DICOM_TAG_OPTICAL_PATH_SEQUENCE)) &&
+        countOpticalPaths == 1)
+    {
+      hasObjectiveLensPower_ = reader.GetFloatValue(
+        objectiveLensPower_, Orthanc::DicomPath(DICOM_TAG_OPTICAL_PATH_SEQUENCE, 0,
+                                                DICOM_TAG_OBJECTIVE_LENS_POWER));
+    }
+    else
+    {
+      hasObjectiveLensPower_ = false;
+    }
   }
 
 
@@ -311,7 +327,9 @@
     imagedVolumeWidth_(0),
     imagedVolumeHeight_(0),
     hasLevel_(false),
-    level_(0)
+    level_(0),
+    hasObjectiveLensPower_(false),
+    objectiveLensPower_(0)
   {
     if (useCache)
     {
@@ -555,4 +573,18 @@
     return (hasLevel_ &&
             level_ == level);
   }
+
+
+  bool DicomPyramidInstance::LookupObjectiveLensPower(float& power) const
+  {
+    if (hasObjectiveLensPower_)
+    {
+      power = objectiveLensPower_;
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
 }
--- a/Framework/Inputs/DicomPyramidInstance.h	Mon Sep 07 20:58:06 2026 +0200
+++ b/Framework/Inputs/DicomPyramidInstance.h	Mon Sep 07 20:58:30 2026 +0200
@@ -54,6 +54,8 @@
     double                              imagedVolumeHeight_;
     bool                                hasLevel_;
     unsigned int                        level_;
+    bool                                hasObjectiveLensPower_;
+    float                               objectiveLensPower_;
 
     void Load(OrthancStone::IOrthancConnection&  orthanc,
               const std::string& instanceId);
@@ -135,5 +137,7 @@
     void SetLevel(unsigned int level);
 
     bool IsLevel(unsigned int level) const;
+
+    bool LookupObjectiveLensPower(float& power) const;
   };
 }
--- a/Framework/Inputs/HierarchicalTiff.cpp	Mon Sep 07 20:58:06 2026 +0200
+++ b/Framework/Inputs/HierarchicalTiff.cpp	Mon Sep 07 20:58:30 2026 +0200
@@ -329,4 +329,10 @@
 
     return found;
   }
+
+
+  bool HierarchicalTiff::LookupObjectiveLensPower(float& power) const
+  {
+    return false;  // TODO - Some basic support for TIFF tags could be inserted here
+  }
 }
--- a/Framework/Inputs/HierarchicalTiff.h	Mon Sep 07 20:58:06 2026 +0200
+++ b/Framework/Inputs/HierarchicalTiff.h	Mon Sep 07 20:58:30 2026 +0200
@@ -111,5 +111,7 @@
     {
       return BackgroundColor();  // No background color
     }
+
+    virtual bool LookupObjectiveLensPower(float& power) const ORTHANC_OVERRIDE;
   };
 }
--- a/Framework/Inputs/ITiledPyramid.h	Mon Sep 07 20:58:06 2026 +0200
+++ b/Framework/Inputs/ITiledPyramid.h	Mon Sep 07 20:58:30 2026 +0200
@@ -72,5 +72,7 @@
     virtual Orthanc::PhotometricInterpretation GetPhotometricInterpretation() const = 0;
 
     virtual BackgroundColor GetBackgroundColor() const = 0;
+
+    virtual bool LookupObjectiveLensPower(float& power) const = 0;
   };
 }
--- a/Framework/Inputs/OnTheFlyPyramid.h	Mon Sep 07 20:58:06 2026 +0200
+++ b/Framework/Inputs/OnTheFlyPyramid.h	Mon Sep 07 20:58:30 2026 +0200
@@ -93,5 +93,10 @@
     }
 
     size_t GetMemoryUsage() const ORTHANC_OVERRIDE;
+
+    virtual bool LookupObjectiveLensPower(float& power) const ORTHANC_OVERRIDE
+    {
+      return false;
+    }
   };
 }
--- a/Framework/Inputs/OpenSlidePyramid.h	Mon Sep 07 20:58:06 2026 +0200
+++ b/Framework/Inputs/OpenSlidePyramid.h	Mon Sep 07 20:58:30 2026 +0200
@@ -87,6 +87,6 @@
 
     size_t GetMemoryUsage() const ORTHANC_OVERRIDE;
 
-    bool LookupObjectiveLensPower(float& power) const;
+    virtual bool LookupObjectiveLensPower(float& power) const ORTHANC_OVERRIDE;
   };
 }
--- a/Framework/Inputs/SingleLevelDecodedPyramid.h	Mon Sep 07 20:58:06 2026 +0200
+++ b/Framework/Inputs/SingleLevelDecodedPyramid.h	Mon Sep 07 20:58:30 2026 +0200
@@ -86,5 +86,10 @@
     {
       return image_.GetSize();
     }
+
+    virtual bool LookupObjectiveLensPower(float& power) const ORTHANC_OVERRIDE
+    {
+      return false;
+    }
   };
 }
--- a/Framework/Inputs/TiledPyramidStatistics.h	Mon Sep 07 20:58:06 2026 +0200
+++ b/Framework/Inputs/TiledPyramidStatistics.h	Mon Sep 07 20:58:30 2026 +0200
@@ -92,5 +92,10 @@
     {
       return source_.GetBackgroundColor();
     }
+
+    virtual bool LookupObjectiveLensPower(float& power) const ORTHANC_OVERRIDE
+    {
+      return source_.LookupObjectiveLensPower(power);
+    }
   };
 }
--- a/Framework/Outputs/InMemoryTiledImage.cpp	Mon Sep 07 20:58:06 2026 +0200
+++ b/Framework/Outputs/InMemoryTiledImage.cpp	Mon Sep 07 20:58:30 2026 +0200
@@ -196,4 +196,10 @@
       }
     }
   }
+
+
+  bool InMemoryTiledImage::LookupObjectiveLensPower(float& power) const
+  {
+    throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);
+  }
 }
--- a/Framework/Outputs/InMemoryTiledImage.h	Mon Sep 07 20:58:06 2026 +0200
+++ b/Framework/Outputs/InMemoryTiledImage.h	Mon Sep 07 20:58:30 2026 +0200
@@ -131,5 +131,7 @@
     {
       return backgroundColor_;
     }
+
+    virtual bool LookupObjectiveLensPower(float& power) const ORTHANC_OVERRIDE;
   };
 }
--- a/ViewerPlugin/Plugin.cpp	Mon Sep 07 20:58:06 2026 +0200
+++ b/ViewerPlugin/Plugin.cpp	Mon Sep 07 20:58:30 2026 +0200
@@ -100,6 +100,13 @@
 
   // New in WSI 2.1 (Default background is white)
   result["BackgroundColor"] = pyramid.GetBackgroundColor().ToHexadecimalString(255, 255, 255);
+
+  // New in WSI 4.0
+  float power;
+  if (pyramid.LookupObjectiveLensPower(power))
+  {
+    result["ObjectiveLensPower"] = power;
+  }
 }