diff OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp @ 1679:5b8b88e5bfd6

successfully running unit tests in WebAssembly
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 24 Nov 2020 12:59:10 +0100
parents 51bab5188a13
children 9ac2a65d4172
line wrap: on
line diff
--- a/OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp	Tue Nov 24 07:40:19 2020 +0100
+++ b/OrthancStone/Sources/Toolbox/DicomInstanceParameters.cpp	Tue Nov 24 12:59:10 2020 +0100
@@ -182,10 +182,10 @@
 
     bool ok = false;
     
-    if (LinearAlgebra::ParseVector(presetWindowingCenters_, dicom, Orthanc::DICOM_TAG_WINDOW_CENTER) &&
-        LinearAlgebra::ParseVector(presetWindowingWidths_, dicom, Orthanc::DICOM_TAG_WINDOW_WIDTH))
+    if (LinearAlgebra::ParseVector(windowingPresetCenters_, dicom, Orthanc::DICOM_TAG_WINDOW_CENTER) &&
+        LinearAlgebra::ParseVector(windowingPresetWidths_, dicom, Orthanc::DICOM_TAG_WINDOW_WIDTH))
     {
-      if (presetWindowingCenters_.size() == presetWindowingWidths_.size())
+      if (windowingPresetCenters_.size() == windowingPresetWidths_.size())
       {
         ok = true;
       }
@@ -199,8 +199,8 @@
     if (!ok)
     {
       // Don't use "Vector::clear()", as it has not the same meaning as "std::vector::clear()"
-      presetWindowingCenters_.resize(0);
-      presetWindowingWidths_.resize(0);
+      windowingPresetCenters_.resize(0);
+      windowingPresetWidths_.resize(0);
     }      
 
     // This computes the "IndexInSeries" metadata from Orthanc (check
@@ -397,18 +397,31 @@
   }
 
 
-  size_t DicomInstanceParameters::GetPresetWindowingsCount() const
+  size_t DicomInstanceParameters::GetWindowingPresetsCount() const
   {
-    assert(data_.presetWindowingCenters_.size() == data_.presetWindowingWidths_.size());
-    return data_.presetWindowingCenters_.size();
+    assert(data_.windowingPresetCenters_.size() == data_.windowingPresetWidths_.size());
+    return data_.windowingPresetCenters_.size();
   }
   
 
-  float DicomInstanceParameters::GetPresetWindowingCenter(size_t i) const
+  float DicomInstanceParameters::GetWindowingPresetCenter(size_t i) const
   {
-    if (i < GetPresetWindowingsCount())
+    if (i < GetWindowingPresetsCount())
+    {
+      return static_cast<float>(data_.windowingPresetCenters_[i]);
+    }
+    else
     {
-      return static_cast<float>(data_.presetWindowingCenters_[i]);
+      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
+    }
+  }
+
+
+  float DicomInstanceParameters::GetWindowingPresetWidth(size_t i) const
+  {
+    if (i < GetWindowingPresetsCount())
+    {
+      return static_cast<float>(data_.windowingPresetWidths_[i]);
     }
     else
     {
@@ -417,19 +430,71 @@
   }
 
 
-  float DicomInstanceParameters::GetPresetWindowingWidth(size_t i) const
+  static void GetWindowingBounds(float& low,
+                                 float& high,
+                                 double center,  // in
+                                 double width)   // in
+  {
+    low = static_cast<float>(center - width / 2.0);
+    high = static_cast<float>(center + width / 2.0);
+  }
+
+  
+  void DicomInstanceParameters::GetWindowingPresetsUnion(float& center,
+                                                         float& width) const
   {
-    if (i < GetPresetWindowingsCount())
+    assert(tags_.get() != NULL);
+    size_t s = GetWindowingPresetsCount();
+
+    if (s > 0)
     {
-      return static_cast<float>(data_.presetWindowingWidths_[i]);
+      // Use the largest windowing given all the preset windowings
+      // that are available in the DICOM tags
+      float low, high;
+      GetWindowingBounds(low, high, GetWindowingPresetCenter(0), GetWindowingPresetWidth(0));
+
+      for (size_t i = 1; i < s; i++)
+      {
+        float a, b;
+        GetWindowingBounds(a, b, GetWindowingPresetCenter(i), GetWindowingPresetWidth(i));
+        low = std::min(low, a);
+        high = std::max(high, b);
+      }
+
+      assert(low <= high);
+
+      if (LinearAlgebra::IsNear(low, high))
+      {
+        // Cannot infer a suitable windowing from the available tags
+        center = 128.0f;
+        width = 256.0f;
+      }
+      else
+      {
+        center = (low + high) / 2.0f;
+        width = (high - low);
+      }
     }
     else
     {
-      throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
+      float a, b;
+      if (tags_->ParseFloat(a, Orthanc::DICOM_TAG_SMALLEST_IMAGE_PIXEL_VALUE) &&
+          tags_->ParseFloat(b, Orthanc::DICOM_TAG_LARGEST_IMAGE_PIXEL_VALUE) &&
+          a < b)
+      {
+        center = (a + b) / 2.0f;
+        width = (b - a);
+      }
+      else
+      {
+        // Cannot infer a suitable windowing from the available tags
+        center = 128.0f;
+        width = 256.0f;
+      }
     }
   }
 
-  
+
   Orthanc::ImageAccessor* DicomInstanceParameters::ConvertToFloat(const Orthanc::ImageAccessor& pixelData) const
   {
     std::unique_ptr<Orthanc::Image> converted(new Orthanc::Image(Orthanc::PixelFormat_Float32, 
@@ -494,9 +559,9 @@
         texture.reset(new FloatTextureSceneLayer(*converted));
       }
 
-      if (GetPresetWindowingsCount() > 0)
+      if (GetWindowingPresetsCount() > 0)
       {
-        texture->SetCustomWindowing(GetPresetWindowingCenter(0), GetPresetWindowingWidth(0));
+        texture->SetCustomWindowing(GetWindowingPresetCenter(0), GetWindowingPresetWidth(0));
       }
       
       switch (GetImageInformation().GetPhotometricInterpretation())