changeset 6590:bf8c7cc07596

new lua callback: OutgoingCStoreInstanceFilter
author Alain Mazy <am@orthanc.team>
date Wed, 18 Feb 2026 20:21:08 +0100
parents 3adbd90885f9
children 76fd43aea734
files NEWS OrthancServer/CMakeLists.txt OrthancServer/Plugins/Engine/OrthancPlugins.cpp OrthancServer/Plugins/Engine/OrthancPlugins.h OrthancServer/Sources/DicomInstanceDestination.cpp OrthancServer/Sources/DicomInstanceDestination.h OrthancServer/Sources/IServerListener.h OrthancServer/Sources/LuaScripting.cpp OrthancServer/Sources/LuaScripting.h OrthancServer/Sources/OrthancRestApi/OrthancRestAnonymizeModify.cpp OrthancServer/Sources/OrthancRestApi/OrthancRestApi.cpp OrthancServer/Sources/OrthancWebDav.cpp OrthancServer/Sources/OutgoingDicomInstance.cpp OrthancServer/Sources/OutgoingDicomInstance.h OrthancServer/Sources/ServerContext.cpp OrthancServer/Sources/ServerContext.h OrthancServer/Sources/ServerJobs/DicomGetScuJob.cpp OrthancServer/Sources/ServerJobs/MergeStudyJob.cpp OrthancServer/Sources/ServerJobs/Operations/ModifyInstanceOperation.cpp OrthancServer/Sources/ServerJobs/ResourceModificationJob.cpp OrthancServer/Sources/ServerJobs/SplitStudyJob.cpp OrthancServer/Sources/ServerToolbox.cpp OrthancServer/Sources/main.cpp OrthancServer/UnitTestsSources/ServerIndexTests.cpp OrthancServer/UnitTestsSources/ServerJobsTests.cpp
diffstat 25 files changed, 343 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/NEWS	Thu Feb 12 18:13:02 2026 +0100
+++ b/NEWS	Wed Feb 18 20:21:08 2026 +0100
@@ -21,6 +21,11 @@
   now returns all resources that do not have any label attached, instead of returning all resources.
   This applies to the default SQLite DB and will apply to the next PostgreSQL plugin (v10.1).
 
+Lua
+---
+
+* Added a new "OutgoingCStoreInstanceFilter()" function. (TODO: document in the book + implement in plugins SDK)
+
 Plugins
 -------
 
--- a/OrthancServer/CMakeLists.txt	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/CMakeLists.txt	Wed Feb 18 20:21:08 2026 +0100
@@ -109,6 +109,7 @@
   ${CMAKE_SOURCE_DIR}/Sources/Database/SQLiteDatabaseWrapper.cpp
   ${CMAKE_SOURCE_DIR}/Sources/Database/StatelessDatabaseOperations.cpp
   ${CMAKE_SOURCE_DIR}/Sources/Database/VoidDatabaseListener.cpp
+  ${CMAKE_SOURCE_DIR}/Sources/DicomInstanceDestination.cpp
   ${CMAKE_SOURCE_DIR}/Sources/DicomInstanceOrigin.cpp
   ${CMAKE_SOURCE_DIR}/Sources/DicomInstanceToStore.cpp
   ${CMAKE_SOURCE_DIR}/Sources/EmbeddedResourceHttpHandler.cpp
@@ -128,6 +129,7 @@
   ${CMAKE_SOURCE_DIR}/Sources/OrthancRestApi/OrthancRestResources.cpp
   ${CMAKE_SOURCE_DIR}/Sources/OrthancRestApi/OrthancRestSystem.cpp
   ${CMAKE_SOURCE_DIR}/Sources/OrthancWebDav.cpp
+  ${CMAKE_SOURCE_DIR}/Sources/OutgoingDicomInstance.cpp
   ${CMAKE_SOURCE_DIR}/Sources/QueryRetrieveHandler.cpp
   ${CMAKE_SOURCE_DIR}/Sources/ResourceFinder.cpp
   ${CMAKE_SOURCE_DIR}/Sources/Search/DatabaseDicomTagConstraint.cpp
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -57,8 +57,10 @@
 #include "../../../OrthancFramework/Sources/SerializationToolbox.h"
 #include "../../../OrthancFramework/Sources/Toolbox.h"
 #include "../../Sources/Database/VoidDatabaseListener.h"
+#include "../../Sources/DicomInstanceToStore.h"
 #include "../../Sources/OrthancConfiguration.h"
 #include "../../Sources/OrthancFindRequestHandler.h"
+#include "../../Sources/OutgoingDicomInstance.h"
 #include "../../Sources/Search/HierarchicalMatcher.h"
 #include "../../Sources/ServerContext.h"
 #include "../../Sources/ServerToolbox.h"
@@ -2950,6 +2952,13 @@
   }
 
 
+  bool OrthancPlugins::FilterOutgoingCStoreInstance(const OutgoingDicomInstance& instance,
+                                                    const Json::Value& simplified)
+  {
+    // TODO
+    return true;
+  }
+
   OrthancPluginReceivedInstanceAction OrthancPlugins::ApplyReceivedInstanceCallbacks(PluginMemoryBuffer64& modified,
                                                                                      const void* receivedDicom,
                                                                                      size_t receivedDicomSize,
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.h	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPlugins.h	Wed Feb 18 20:21:08 2026 +0100
@@ -66,6 +66,7 @@
 {
   class HttpServer;
   class ServerContext;
+  class OutgoingDicomInstance;
 
   class OrthancPlugins : 
     public IHttpHandler, 
@@ -333,6 +334,10 @@
                                               const DicomInstanceToStore& instance,
                                               const Json::Value& simplified) ORTHANC_OVERRIDE;
 
+    // TODO
+    virtual bool FilterOutgoingCStoreInstance(const OutgoingDicomInstance& instance,
+                                              const Json::Value& simplified) ORTHANC_OVERRIDE;
+
     OrthancPluginReceivedInstanceAction ApplyReceivedInstanceCallbacks(PluginMemoryBuffer64& modified,
                                                                        const void* receivedDicomBuffer,
                                                                        size_t receivedDicomBufferSize,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancServer/Sources/DicomInstanceDestination.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -0,0 +1,37 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2023 Osimis S.A., Belgium
+ * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium
+ * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "PrecompiledHeadersServer.h"
+#include "DicomInstanceDestination.h"
+
+
+namespace Orthanc
+{
+  void DicomInstanceDestination::Format(Json::Value& result) const
+  {
+    result = Json::objectValue;
+
+    result["RemoteIp"] = remoteIp_;
+    result["RemoteAet"] = remoteAet_;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancServer/Sources/DicomInstanceDestination.h	Wed Feb 18 20:21:08 2026 +0100
@@ -0,0 +1,61 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2023 Osimis S.A., Belgium
+ * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium
+ * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include <string>
+#include <json/value.h>
+
+
+namespace Orthanc
+{
+  class DicomInstanceDestination
+  {
+  private:
+    std::string   remoteIp_;
+    std::string   remoteAet_;
+
+  public:
+    DicomInstanceDestination(const std::string& remoteIp, const std::string& remoteAet) :
+      remoteIp_(remoteIp),
+      remoteAet_(remoteAet)
+    {
+    }
+
+    DicomInstanceDestination()
+    {
+    }
+
+    const std::string& GetRemoteIp() const
+    {
+      return remoteIp_;
+    }
+
+    const std::string& GetRemoteAet() const
+    {
+      return remoteAet_;
+    }
+
+    void Format(Json::Value& result) const;
+  };
+}
--- a/OrthancServer/Sources/IServerListener.h	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Sources/IServerListener.h	Wed Feb 18 20:21:08 2026 +0100
@@ -23,7 +23,6 @@
 
 #pragma once
 
-#include "DicomInstanceToStore.h"
 #include "ServerIndexChange.h"
 #include "JobEvent.h"
 
@@ -31,6 +30,9 @@
 
 namespace Orthanc
 {
+  class DicomInstanceToStore;
+  class OutgoingDicomInstance;
+
   class IServerListener : public boost::noncopyable
   {
   public:
@@ -58,5 +60,12 @@
     virtual bool FilterIncomingCStoreInstance(uint16_t& dimseStatus,
                                               const DicomInstanceToStore& instance,
                                               const Json::Value& simplified) = 0;
+
+    /**
+     * Returns "false" if the DICOM instance must NOT be sent to the target modality.
+     */
+    virtual bool FilterOutgoingCStoreInstance(const OutgoingDicomInstance& instance,
+                                              const Json::Value& simplified) = 0;
+
   };
 }
--- a/OrthancServer/Sources/LuaScripting.cpp	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Sources/LuaScripting.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -24,8 +24,10 @@
 #include "PrecompiledHeadersServer.h"
 #include "LuaScripting.h"
 
+#include "DicomInstanceToStore.h"
 #include "OrthancConfiguration.h"
 #include "OrthancRestApi/OrthancRestApi.h"
+#include "OutgoingDicomInstance.h"
 #include "ServerContext.h"
 
 #include "../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h"
@@ -1080,6 +1082,32 @@
   }
 
 
+  bool LuaScripting::FilterOutgoingCStoreInstance(const OutgoingDicomInstance& instance,
+                                                  const Json::Value& simplified)
+  {
+    static const char* NAME = "OutgoingCStoreInstanceFilter";
+
+    boost::recursive_mutex::scoped_lock lock(mutex_);
+
+    if (lua_.IsExistingFunction(NAME))
+    {
+      LuaFunctionCall call(lua_, NAME);
+      call.PushJson(simplified);
+
+      Json::Value destination;
+      instance.GetDestination().Format(destination);
+      call.PushJson(destination);
+
+      if (!call.ExecutePredicate())
+      {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+
   void LuaScripting::Execute(const std::string& command)
   {
     pendingEvents_.Enqueue(new ExecuteEvent(command));
--- a/OrthancServer/Sources/LuaScripting.h	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Sources/LuaScripting.h	Wed Feb 18 20:21:08 2026 +0100
@@ -23,7 +23,6 @@
 
 #pragma once
 
-#include "DicomInstanceToStore.h"
 #include "ServerIndexChange.h"
 #include "JobEvent.h"
 #include "ServerJobs/LuaJobManager.h"
@@ -34,6 +33,8 @@
 namespace Orthanc
 {
   class ServerContext;
+  class OutgoingDicomInstance;
+  class DicomInstanceToStore;
 
   class LuaScripting : public boost::noncopyable
   {
@@ -129,6 +130,9 @@
                                       const DicomInstanceToStore& instance,
                                       const Json::Value& simplified);
 
+    bool FilterOutgoingCStoreInstance(const OutgoingDicomInstance& instance,
+                                      const Json::Value& simplified);
+
     void Execute(const std::string& command);
 
     void SignalJobEvent(const JobEvent& event);
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestAnonymizeModify.cpp	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestAnonymizeModify.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -27,6 +27,7 @@
 #include "../../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h"
 #include "../../../OrthancFramework/Sources/Logging.h"
 #include "../../../OrthancFramework/Sources/SerializationToolbox.h"
+#include "../DicomInstanceToStore.h"
 #include "../OrthancConfiguration.h"
 #include "../ServerContext.h"
 #include "../ServerJobs/MergeStudyJob.h"
--- a/OrthancServer/Sources/OrthancRestApi/OrthancRestApi.cpp	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestApi.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -30,6 +30,7 @@
 #include "../../../OrthancFramework/Sources/MetricsRegistry.h"
 #include "../../../OrthancFramework/Sources/SerializationToolbox.h"
 #include "../../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h"
+#include "../DicomInstanceToStore.h"
 #include "../OrthancConfiguration.h"
 #include "../ServerContext.h"
 
--- a/OrthancServer/Sources/OrthancWebDav.cpp	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Sources/OrthancWebDav.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -30,6 +30,7 @@
 #include "../../OrthancFramework/Sources/Logging.h"
 #include "ResourceFinder.h"
 #include "Search/DatabaseLookup.h"
+#include "DicomInstanceToStore.h"
 #include "ServerContext.h"
 
 #include <boost/regex.hpp>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancServer/Sources/OutgoingDicomInstance.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -0,0 +1,62 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2023 Osimis S.A., Belgium
+ * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium
+ * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "PrecompiledHeadersServer.h"
+#include "OutgoingDicomInstance.h"
+
+#include "OrthancConfiguration.h"
+
+#include "../../OrthancFramework/Sources/DicomParsing/ParsedDicomFile.h"
+#include "../../OrthancFramework/Sources/OrthancException.h"
+#include "../../OrthancFramework/Sources/Toolbox.h"
+
+
+namespace Orthanc
+{
+  OutgoingDicomInstance* OutgoingDicomInstance::CreateFromBuffer(const std::string& buffer)
+  {
+    return CreateFromBuffer(buffer.empty() ? NULL : buffer.c_str(), buffer.size());
+  }
+
+  OutgoingDicomInstance* OutgoingDicomInstance::CreateFromBuffer(const void* buffer, size_t size)
+  {
+    return new OutgoingDicomInstance(new ParsedDicomFile(buffer, size));
+  }
+
+  void OutgoingDicomInstance::GetSimplifiedJson(Json::Value& simplifiedTags) const
+  {
+    if (dicom_.get() == NULL)
+    {
+      throw OrthancException(ErrorCode_BadSequenceOfCalls);
+    }
+
+    std::set<DicomTag> allMainDicomTags;
+    DicomMap::GetAllMainDicomTags(allMainDicomTags);
+
+    Json::Value dicomAsJson;
+    OrthancConfiguration::DefaultDicomDatasetToJson(dicomAsJson, *dicom_, allMainDicomTags); // don't crop any main dicom tags
+
+    Toolbox::SimplifyDicomAsJson(simplifiedTags, dicomAsJson, DicomToJsonFormat_Human);
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancServer/Sources/OutgoingDicomInstance.h	Wed Feb 18 20:21:08 2026 +0100
@@ -0,0 +1,67 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2023 Osimis S.A., Belgium
+ * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium
+ * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "../../OrthancFramework/Sources/DicomFormat/DicomMap.h"
+#include "DicomInstanceDestination.h"
+#include "ServerEnumerations.h"
+
+#include <boost/shared_ptr.hpp>
+
+class DcmDataset;
+
+namespace Orthanc
+{
+  class ParsedDicomFile;
+
+  class OutgoingDicomInstance : public boost::noncopyable
+  {
+    DicomInstanceDestination            destination_;
+    std::unique_ptr<ParsedDicomFile>    dicom_;
+
+    OutgoingDicomInstance(ParsedDicomFile* dicom) :
+      dicom_(dicom)
+    {}
+
+  public:
+    // WARNING: The source in the factory methods is *not* copied and
+    // must *not* be deallocated as long as this wrapper object is alive
+    static OutgoingDicomInstance* CreateFromBuffer(const void* buffer,
+                                                   size_t size);
+
+    static OutgoingDicomInstance* CreateFromBuffer(const std::string& buffer);
+
+    void SetDestination(const DicomInstanceDestination& destination)
+    {
+      destination_ = destination;
+    }
+
+    const DicomInstanceDestination& GetDestination() const
+    {
+      return destination_;
+    } 
+    
+    void GetSimplifiedJson(Json::Value& dicomAsJson) const;
+  };
+}
--- a/OrthancServer/Sources/ServerContext.cpp	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Sources/ServerContext.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -40,6 +40,7 @@
 #include "../../OrthancFramework/Sources/MetricsRegistry.h"
 #include "../Plugins/Engine/OrthancPlugins.h"
 
+#include "DicomInstanceToStore.h"
 #include "OrthancConfiguration.h"
 #include "OrthancRestApi/OrthancRestApi.h"
 #include "ResourceFinder.h"
@@ -47,6 +48,7 @@
 #include "ServerJobs/OrthancJobUnserializer.h"
 #include "ServerToolbox.h"
 #include "StorageCommitmentReports.h"
+#include "OutgoingDicomInstance.h"
 
 #include <dcmtk/dcmdata/dcfilefo.h>
 #include <dcmtk/dcmnet/dimse.h>
@@ -1985,6 +1987,36 @@
     const void* data = dicom.empty() ? NULL : dicom.c_str();
     const RemoteModalityParameters& modality = connection.GetParameters().GetRemoteModality();
 
+    // Filter out outgoing C-Store instances
+    {
+      boost::shared_lock<boost::shared_mutex> lock(listenersMutex_);
+
+      std::unique_ptr<OutgoingDicomInstance> outgoingInstance(OutgoingDicomInstance::CreateFromBuffer(dicom));
+      outgoingInstance->SetDestination(DicomInstanceDestination(connection.GetParameters().GetRemoteModality().GetHost(),
+                                                                connection.GetParameters().GetRemoteModality().GetApplicationEntityTitle()));
+
+      Json::Value simplifiedTags;
+      outgoingInstance->GetSimplifiedJson(simplifiedTags);
+
+      for (ServerListeners::iterator it = listeners_.begin(); it != listeners_.end(); ++it)
+      {
+        try
+        {
+          if (!it->GetListener().FilterOutgoingCStoreInstance(*outgoingInstance, simplifiedTags))
+          {
+            return;
+          }
+        }
+        catch (OrthancException& e)
+        {
+          LOG(ERROR) << "Error in the " << it->GetDescription() 
+                      << " callback while sending an instance: " << e.What()
+                      << " (code " << e.GetErrorCode() << ")";
+          throw;
+        }
+      }
+    }
+
     if (!transcodeDicomProtocol_ ||
         !modality.IsTranscodingAllowed())
     {
--- a/OrthancServer/Sources/ServerContext.h	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Sources/ServerContext.h	Wed Feb 18 20:21:08 2026 +0100
@@ -43,6 +43,7 @@
 namespace Orthanc
 {
   class DicomInstanceToStore;
+  class OutgoingDicomInstance;
   class IPluginStorageArea;
   class JobsEngine;
   class MetricsRegistry;
@@ -140,6 +141,13 @@
       {
         return context_.filterLua_.FilterIncomingCStoreInstance(dimseStatus, instance, simplified);
       }
+
+      virtual bool FilterOutgoingCStoreInstance(const OutgoingDicomInstance& instance,
+                                                const Json::Value& simplified) ORTHANC_OVERRIDE
+      {
+        return context_.filterLua_.FilterOutgoingCStoreInstance(instance, simplified);
+      }
+
     };
     
     class ServerListener
--- a/OrthancServer/Sources/ServerJobs/DicomGetScuJob.cpp	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Sources/ServerJobs/DicomGetScuJob.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -25,6 +25,7 @@
 
 #include "../../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h"
 #include "../../../OrthancFramework/Sources/SerializationToolbox.h"
+#include "../DicomInstanceToStore.h"
 #include "../ServerContext.h"
 #include <dcmtk/dcmnet/dimse.h>
 #include <algorithm>
--- a/OrthancServer/Sources/ServerJobs/MergeStudyJob.cpp	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Sources/ServerJobs/MergeStudyJob.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -26,6 +26,7 @@
 #include "../../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h"
 #include "../../../OrthancFramework/Sources/Logging.h"
 #include "../../../OrthancFramework/Sources/SerializationToolbox.h"
+#include "../DicomInstanceToStore.h"
 #include "../OrthancConfiguration.h"
 #include "../ServerContext.h"
 
--- a/OrthancServer/Sources/ServerJobs/Operations/ModifyInstanceOperation.cpp	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Sources/ServerJobs/Operations/ModifyInstanceOperation.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -25,6 +25,7 @@
 #include "ModifyInstanceOperation.h"
 
 #include "DicomInstanceOperationValue.h"
+#include "../../DicomInstanceToStore.h"
 #include "../../ServerContext.h"
 
 #include "../../../../OrthancFramework/Sources/Logging.h"
--- a/OrthancServer/Sources/ServerJobs/ResourceModificationJob.cpp	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Sources/ServerJobs/ResourceModificationJob.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -26,6 +26,7 @@
 
 #include "../../../OrthancFramework/Sources/Logging.h"
 #include "../../../OrthancFramework/Sources/SerializationToolbox.h"
+#include "../DicomInstanceToStore.h"
 #include "../ServerContext.h"
 
 #include <dcmtk/dcmdata/dcfilefo.h>
--- a/OrthancServer/Sources/ServerJobs/SplitStudyJob.cpp	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Sources/ServerJobs/SplitStudyJob.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -26,6 +26,7 @@
 #include "../../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h"
 #include "../../../OrthancFramework/Sources/Logging.h"
 #include "../../../OrthancFramework/Sources/SerializationToolbox.h"
+#include "../DicomInstanceToStore.h"
 #include "../ServerContext.h"
 
 
--- a/OrthancServer/Sources/ServerToolbox.cpp	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Sources/ServerToolbox.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -31,6 +31,7 @@
 #include "../../OrthancFramework/Sources/OrthancException.h"
 #include "Database/IDatabaseWrapper.h"
 #include "Database/ResourcesContent.h"
+#include "DicomInstanceToStore.h"
 #include "OrthancConfiguration.h"
 #include "ServerContext.h"
 
--- a/OrthancServer/Sources/main.cpp	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/Sources/main.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -37,6 +37,7 @@
 #include "../../OrthancFramework/Sources/Lua/LuaFunctionCall.h"
 #include "../Plugins/Engine/OrthancPlugins.h"
 #include "Database/SQLiteDatabaseWrapper.h"
+#include "DicomInstanceToStore.h"
 #include "EmbeddedResourceHttpHandler.h"
 #include "OrthancConfiguration.h"
 #include "OrthancFindRequestHandler.h"
--- a/OrthancServer/UnitTestsSources/ServerIndexTests.cpp	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/UnitTestsSources/ServerIndexTests.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -32,6 +32,7 @@
 #include "../../OrthancFramework/Sources/Logging.h"
 
 #include "../Sources/Database/SQLiteDatabaseWrapper.h"
+#include "../Sources/DicomInstanceToStore.h"
 #include "../Sources/OrthancConfiguration.h"
 #include "../Sources/Search/DatabaseLookup.h"
 #include "../Sources/ServerContext.h"
--- a/OrthancServer/UnitTestsSources/ServerJobsTests.cpp	Thu Feb 12 18:13:02 2026 +0100
+++ b/OrthancServer/UnitTestsSources/ServerJobsTests.cpp	Wed Feb 18 20:21:08 2026 +0100
@@ -32,6 +32,7 @@
 #include "../../OrthancFramework/Sources/SerializationToolbox.h"
 
 #include "../Sources/Database/SQLiteDatabaseWrapper.h"
+#include "../Sources/DicomInstanceToStore.h"
 #include "../Sources/ServerContext.h"
 #include "../Sources/ServerJobs/LuaJobManager.h"
 #include "../Sources/ServerJobs/OrthancJobUnserializer.h"