diff Framework/Volumes/ImageBuffer3D.cpp @ 119:ba83e38cf3ff wasm

rendering of rt-dose
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 02 Oct 2017 22:01:41 +0200
parents 2eca030792aa
children e2fe9352f240
line wrap: on
line diff
--- a/Framework/Volumes/ImageBuffer3D.cpp	Mon Oct 02 14:31:26 2017 +0200
+++ b/Framework/Volumes/ImageBuffer3D.cpp	Mon Oct 02 22:01:41 2017 +0200
@@ -112,12 +112,15 @@
   ImageBuffer3D::ImageBuffer3D(Orthanc::PixelFormat format,
                                unsigned int width,
                                unsigned int height,
-                               unsigned int depth) :
+                               unsigned int depth,
+                               bool computeRange) :
     image_(format, width, height * depth, false),
     format_(format),
     width_(width),
     height_(height),
-    depth_(depth)
+    depth_(depth),
+    computeRange_(computeRange),
+    hasRange_(false)
   {
     GeometryToolbox::AssignVector(voxelDimensions_, 1, 1, 1);
 
@@ -265,6 +268,91 @@
   }
 
 
+  void ImageBuffer3D::ExtendImageRange(const Orthanc::ImageAccessor& slice)
+  {
+    if (!computeRange_ ||
+        slice.GetWidth() == 0 ||
+        slice.GetHeight() == 0)
+    {
+      return;
+    }
+
+    float sliceMin, sliceMax;
+      
+    switch (slice.GetFormat())
+    {
+      case Orthanc::PixelFormat_Grayscale8:
+      case Orthanc::PixelFormat_Grayscale16:
+      case Orthanc::PixelFormat_Grayscale32:
+      case Orthanc::PixelFormat_SignedGrayscale16:
+      {
+        int64_t a, b;
+        Orthanc::ImageProcessing::GetMinMaxIntegerValue(a, b, slice);
+        sliceMin = static_cast<float>(a);
+        sliceMax = static_cast<float>(b);
+        break;
+      }
+
+      case Orthanc::PixelFormat_Float32:
+        Orthanc::ImageProcessing::GetMinMaxFloatValue(sliceMin, sliceMax, slice);
+        break;
+
+      default:
+        return;
+    }
+
+    if (hasRange_)
+    {
+      minValue_ = std::min(minValue_, sliceMin);
+      maxValue_ = std::max(maxValue_, sliceMax);
+    }
+    else
+    {
+      hasRange_ = true;
+      minValue_ = sliceMin;
+      maxValue_ = sliceMax;
+    }
+  }
+
+
+  bool ImageBuffer3D::GetRange(float& minValue,
+                               float& maxValue) const
+  {
+    if (hasRange_)
+    {
+      minValue = minValue_;
+      maxValue = maxValue_;
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+
+
+  bool ImageBuffer3D::FitWindowingToRange(RenderStyle& style,
+                                          const DicomFrameConverter& converter) const
+  {
+    if (hasRange_)
+    {
+      style.windowing_ = ImageWindowing_Custom;
+      style.customWindowCenter_ = converter.Apply((minValue_ + maxValue_) / 2.0);
+      style.customWindowWidth_ = converter.Apply(maxValue_ - minValue_);
+      
+      if (style.customWindowWidth_ > 1)
+      {
+        return true;
+      }
+    }
+
+    style.windowing_ = ImageWindowing_Custom;
+    style.customWindowCenter_ = 128.0;
+    style.customWindowWidth_ = 256.0;
+    return false;
+  }
+
+
   ImageBuffer3D::SliceReader::SliceReader(ImageBuffer3D& that,
                                           VolumeProjection projection,
                                           unsigned int slice)
@@ -299,6 +387,10 @@
         // TODO
         throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented);          
       }
+
+      // Update the dynamic range of the underlying image, if
+      // "computeRange_" is set to true
+      that_.ExtendImageRange(accessor_);
     }
   }
 
@@ -306,7 +398,8 @@
   ImageBuffer3D::SliceWriter::SliceWriter(ImageBuffer3D& that,
                                           VolumeProjection projection,
                                           unsigned int slice) :
-  modified_(false)
+    that_(that),
+    modified_(false)
   {
     switch (projection)
     {