changeset 1996:6e4ef6e3b2bf

linear interpolation of images can be turned off in the user preferences
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 01 Nov 2022 19:41:03 +0100
parents f2a094fa8c33
children c622219a3388
files Applications/StoneWebViewer/NEWS Applications/StoneWebViewer/WebApplication/app.js Applications/StoneWebViewer/WebApplication/index.html Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp
diffstat 4 files changed, 59 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/Applications/StoneWebViewer/NEWS	Tue Nov 01 19:04:34 2022 +0100
+++ b/Applications/StoneWebViewer/NEWS	Tue Nov 01 19:41:03 2022 +0100
@@ -10,6 +10,7 @@
 * Added vertical slider showing position of the current frame inside the series
 * Display of orientation markers
 * The text field with the instance number is editable to go to a specific instance
+* Linear interpolation of images can be turned off in the user preferences
 * New configuration options:
   - "ShowInfoPanelAtStartup" to control the info panel at startup
   - "ShowUserPreferencesButton" to show the button for setting preferences
--- a/Applications/StoneWebViewer/WebApplication/app.js	Tue Nov 01 19:04:34 2022 +0100
+++ b/Applications/StoneWebViewer/WebApplication/app.js	Tue Nov 01 19:41:03 2022 +0100
@@ -445,6 +445,7 @@
       // User preferences (stored in the local storage)
       settingNotDiagnostic: true,
       settingSoftwareRendering: false,
+      settingLinearInterpolation: true,
 
       layoutCountX: 1,
       layoutCountY: 1,
@@ -523,6 +524,9 @@
     },
     settingSoftwareRendering: function(newVal, oldVal) {
       localStorage.settingSoftwareRendering = (newVal ? '1' : '0');
+    },
+    settingLinearInterpolation: function(newVal, oldVal) {
+      localStorage.settingLinearInterpolation = (newVal ? '1' : '0');
     }
   },
   methods: {
@@ -920,6 +924,8 @@
     ApplyPreferences: function() {
       this.modalPreferences = false;
 
+      stone.SetLinearInterpolation(localStorage.settingLinearInterpolation);
+
       if ((stone.IsSoftwareRendering() != 0) != this.settingSoftwareRendering) {
         document.location.reload();
       }
@@ -1141,6 +1147,8 @@
   },
   
   mounted: function() {
+    // Warning: In this function, the "stone" global object is not initialized yet!
+    
     this.SetViewportLayout('1x1');
 
     if (localStorage.settingNotDiagnostic) {
@@ -1151,6 +1159,10 @@
       this.settingSoftwareRendering = (localStorage.settingSoftwareRendering == '1');
     }
 
+    if (localStorage.settingLinearInterpolation) {
+      this.settingLinearInterpolation = (localStorage.settingLinearInterpolation == '1');
+    }
+
     var that = this;
     
     window.addEventListener('VirtualSeriesThumbnailLoaded', function(args) {
@@ -1190,7 +1202,8 @@
   stone.Setup(Module);
   stone.SetDicomWebRoot(app.globalConfiguration.DicomWebRoot,
                         true /* assume "/rendered" is available in DICOMweb (could be a configuration option) */);
-  stone.SetSoftwareRendering(localStorage.settingSoftwareRendering == '1');
+  stone.SetSoftwareRendering(app.settingSoftwareRendering);
+  stone.SetLinearInterpolation(app.settingLinearInterpolation);
 
   if ('DicomCacheSize' in app.globalConfiguration) {
     stone.SetDicomCacheSize(app.globalConfiguration.DicomCacheSize);
--- a/Applications/StoneWebViewer/WebApplication/index.html	Tue Nov 01 19:04:34 2022 +0100
+++ b/Applications/StoneWebViewer/WebApplication/index.html	Tue Nov 01 19:41:03 2022 +0100
@@ -85,7 +85,11 @@
               </label>
               <br>
             </div>
-            <label>Use software rendering (will reload the viewer)
+            <label>Enable linear interpolation
+              <input type="checkbox" style="margin-left: 20px" v-model="settingLinearInterpolation">
+            </label>
+            <br>
+            <label>Use software rendering (slower, will reload the viewer)
               <input type="checkbox" style="margin-left: 20px" v-model="settingSoftwareRendering">
             </label>
             <br><br>
--- a/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp	Tue Nov 01 19:04:34 2022 +0100
+++ b/Applications/StoneWebViewer/WebAssembly/StoneWebViewer.cpp	Tue Nov 01 19:41:03 2022 +0100
@@ -2022,6 +2022,8 @@
   // the center of the top-left pixel
   boost::shared_ptr<OrthancStone::AnnotationsSceneLayer>  stoneAnnotations_;
 
+  bool linearInterpolation_;
+
 
   void ScheduleNextPrefetch()
   {
@@ -2159,7 +2161,7 @@
 
     assert(layer.get() != NULL);
 
-    layer->SetLinearInterpolation(true);
+    layer->SetLinearInterpolation(linearInterpolation_);
 
     double pixelSpacingX, pixelSpacingY;
 
@@ -2213,6 +2215,7 @@
       if (accessor.IsValid())
       {
         overlay.reset(accessor.CreateTexture());
+        overlay->SetLinearInterpolation(false);
       }
     }
 
@@ -2507,7 +2510,8 @@
                  const OrthancStone::DicomSource& source,
                  const std::string& canvas,
                  boost::shared_ptr<FramesCache> cache,
-                 bool softwareRendering) :
+                 bool softwareRendering,
+                 bool linearInterpolation) :
     context_(context),
     source_(source),
     framesCache_(cache),
@@ -2519,7 +2523,8 @@
     centralPhysicalWidth_(1),
     centralPhysicalHeight_(1),
     centralPixelSpacingX_(1),
-    centralPixelSpacingY_(1)
+    centralPixelSpacingY_(1),
+    linearInterpolation_(linearInterpolation)
   {
     if (!framesCache_)
     {
@@ -2700,10 +2705,11 @@
                                                   const OrthancStone::DicomSource& source,
                                                   const std::string& canvas,
                                                   boost::shared_ptr<FramesCache> cache,
-                                                  bool softwareRendering)
+                                                  bool softwareRendering,
+                                                  bool linearInterpolation)
   {
     boost::shared_ptr<ViewerViewport> viewport(
-      new ViewerViewport(context, source, canvas, cache, softwareRendering));
+      new ViewerViewport(context, source, canvas, cache, softwareRendering, linearInterpolation));
 
     {
       std::unique_ptr<OrthancStone::ILoadersContext::ILock> lock(context.Lock());
@@ -3420,6 +3426,15 @@
       }
     }    
   }
+
+  void SetLinearInterpolation(bool linearInterpolation)
+  {
+    if (linearInterpolation_ != linearInterpolation)
+    {
+      linearInterpolation_ = linearInterpolation;
+      Redraw();
+    }
+  }
 };
 
 
@@ -3689,6 +3704,7 @@
 static boost::shared_ptr<OrthancStone::WebAssemblyLoadersContext> context_;
 static std::string stringBuffer_;
 static bool softwareRendering_ = false;
+static bool linearInterpolation_ = true;
 static WebViewerAction leftButtonAction_ = WebViewerAction_Windowing;
 static WebViewerAction middleButtonAction_ = WebViewerAction_Pan;
 static WebViewerAction rightButtonAction_ = WebViewerAction_Zoom;
@@ -3735,7 +3751,7 @@
   if (found == allViewports_.end())
   {
     boost::shared_ptr<ViewerViewport> viewport(
-      ViewerViewport::Create(*context_, source_, canvas, framesCache_, softwareRendering_));
+      ViewerViewport::Create(*context_, source_, canvas, framesCache_, softwareRendering_, linearInterpolation_));
     viewport->SetMouseButtonActions(leftButtonAction_, middleButtonAction_, rightButtonAction_);
     viewport->AcquireObserver(new WebAssemblyObserver);
     viewport->SetOsiriXAnnotations(osiriXAnnotations_);
@@ -4254,6 +4270,23 @@
 
 
   EMSCRIPTEN_KEEPALIVE
+  void SetLinearInterpolation(int linearInterpolation)
+  {
+    linearInterpolation_ = linearInterpolation;
+
+    try
+    {
+      for (Viewports::iterator it = allViewports_.begin(); it != allViewports_.end(); ++it)
+      {
+        assert(it->second != NULL);
+        it->second->SetLinearInterpolation(linearInterpolation);
+      }
+    }
+    EXTERN_CATCH_EXCEPTIONS;
+  }  
+
+
+  EMSCRIPTEN_KEEPALIVE
   void SetMouseButtonActions(int leftAction,
                              int middleAction,
                              int rightAction)