# HG changeset patch # User Sebastien Jodogne # Date 1587133310 -7200 # Node ID 1491d501836a23a966b3639a4bd1d189b792573f # Parent 67e765d51bdfd2327ac232e9b4cdf9369f6b51cd actual implementation of OrthancPluginRegisterIncomingDicomInstanceFilter() diff -r 67e765d51bdf -r 1491d501836a OrthancServer/DicomInstanceToStore.cpp --- a/OrthancServer/DicomInstanceToStore.cpp Thu Apr 16 18:46:11 2020 +0200 +++ b/OrthancServer/DicomInstanceToStore.cpp Fri Apr 17 16:21:50 2020 +0200 @@ -461,15 +461,15 @@ } - const void* DicomInstanceToStore::GetBufferData() + const void* DicomInstanceToStore::GetBufferData() const { - return pimpl_->GetBufferData(); + return const_cast(*pimpl_).GetBufferData(); } - size_t DicomInstanceToStore::GetBufferSize() + size_t DicomInstanceToStore::GetBufferSize() const { - return pimpl_->GetBufferSize(); + return const_cast(*pimpl_).GetBufferSize(); } @@ -479,9 +479,9 @@ } - const Json::Value& DicomInstanceToStore::GetJson() + const Json::Value& DicomInstanceToStore::GetJson() const { - return pimpl_->GetJson(); + return const_cast(*pimpl_).GetJson(); } diff -r 67e765d51bdf -r 1491d501836a OrthancServer/DicomInstanceToStore.h --- a/OrthancServer/DicomInstanceToStore.h Thu Apr 16 18:46:11 2020 +0200 +++ b/OrthancServer/DicomInstanceToStore.h Fri Apr 17 16:21:50 2020 +0200 @@ -79,13 +79,13 @@ MetadataType metadata, const std::string& value); - const void* GetBufferData(); + const void* GetBufferData() const; - size_t GetBufferSize(); + size_t GetBufferSize() const; const DicomMap& GetSummary(); - const Json::Value& GetJson(); + const Json::Value& GetJson() const; bool LookupTransferSyntax(std::string& result) const; diff -r 67e765d51bdf -r 1491d501836a Plugins/Engine/OrthancPlugins.cpp --- a/Plugins/Engine/OrthancPlugins.cpp Thu Apr 16 18:46:11 2020 +0200 +++ b/Plugins/Engine/OrthancPlugins.cpp Fri Apr 17 16:21:50 2020 +0200 @@ -825,6 +825,7 @@ typedef std::list OnChangeCallbacks; typedef std::list IncomingHttpRequestFilters; typedef std::list IncomingHttpRequestFilters2; + typedef std::list IncomingDicomInstanceFilters; typedef std::list DecodeImageCallbacks; typedef std::list JobsUnserializers; typedef std::list RefreshMetricsCallbacks; @@ -844,6 +845,7 @@ _OrthancPluginMoveCallback moveCallbacks_; IncomingHttpRequestFilters incomingHttpRequestFilters_; IncomingHttpRequestFilters2 incomingHttpRequestFilters2_; + IncomingDicomInstanceFilters incomingDicomInstanceFilters_; RefreshMetricsCallbacks refreshMetricsCallbacks_; StorageCommitmentScpCallbacks storageCommitmentScpCallbacks_; std::unique_ptr storageArea_; @@ -1782,7 +1784,33 @@ } - + bool OrthancPlugins::FilterIncomingInstance(const DicomInstanceToStore& instance, + const Json::Value& simplified) + { + boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_); + + for (PImpl::IncomingDicomInstanceFilters::const_iterator + filter = pimpl_->incomingDicomInstanceFilters_.begin(); + filter != pimpl_->incomingDicomInstanceFilters_.end(); ++filter) + { + int32_t allowed = (*filter) ( + reinterpret_cast(&instance)); + + if (allowed == 0) + { + return false; + } + else if (allowed != 1) + { + // The callback is only allowed to answer 0 or 1 + throw OrthancException(ErrorCode_Plugin); + } + } + + return true; + } + + void OrthancPlugins::SignalChangeInternal(OrthancPluginChangeType changeType, OrthancPluginResourceType resourceType, const char* resource) @@ -1967,6 +1995,16 @@ } + void OrthancPlugins::RegisterIncomingDicomInstanceFilter(const void* parameters) + { + const _OrthancPluginIncomingDicomInstanceFilter& p = + *reinterpret_cast(parameters); + + LOG(INFO) << "Plugin has registered a callback to filter incoming DICOM instances"; + pimpl_->incomingDicomInstanceFilters_.push_back(p.callback); + } + + void OrthancPlugins::RegisterRefreshMetricsCallback(const void* parameters) { const _OrthancPluginRegisterRefreshMetricsCallback& p = @@ -2419,8 +2457,8 @@ const _OrthancPluginAccessDicomInstance& p = *reinterpret_cast(parameters); - DicomInstanceToStore& instance = - *reinterpret_cast(p.instance); + const DicomInstanceToStore& instance = + *reinterpret_cast(p.instance); switch (service) { @@ -2469,6 +2507,22 @@ *p.resultOrigin = Plugins::Convert(instance.GetOrigin().GetRequestOrigin()); return; + case _OrthancPluginService_GetInstanceTransferSyntaxUid: // New in Orthanc 1.6.1 + { + std::string s; + if (!instance.LookupTransferSyntax(s)) + { + s.clear(); + } + + *p.resultStringToFree = CopyString(s); + return; + } + + case _OrthancPluginService_HasInstancePixelData: // New in Orthanc 1.6.1 + *p.resultInt64 = instance.HasPixelData(); + return; + default: throw OrthancException(ErrorCode_InternalError); } @@ -3420,6 +3474,8 @@ case _OrthancPluginService_HasInstanceMetadata: case _OrthancPluginService_GetInstanceMetadata: case _OrthancPluginService_GetInstanceOrigin: + case _OrthancPluginService_GetInstanceTransferSyntaxUid: + case _OrthancPluginService_HasInstancePixelData: AccessDicomInstance(service, parameters); return true; @@ -4034,6 +4090,10 @@ RegisterIncomingHttpRequestFilter2(parameters); return true; + case _OrthancPluginService_RegisterIncomingDicomInstanceFilter: + RegisterIncomingDicomInstanceFilter(parameters); + return true; + case _OrthancPluginService_RegisterRefreshMetricsCallback: RegisterRefreshMetricsCallback(parameters); return true; @@ -4477,46 +4537,50 @@ getValues[i] = getArguments[i].second.c_str(); } - // Improved callback with support for GET arguments, since Orthanc 1.3.0 - for (PImpl::IncomingHttpRequestFilters2::const_iterator - filter = pimpl_->incomingHttpRequestFilters2_.begin(); - filter != pimpl_->incomingHttpRequestFilters2_.end(); ++filter) { - int32_t allowed = (*filter) (cMethod, uri, ip, - httpKeys.size(), - httpKeys.empty() ? NULL : &httpKeys[0], - httpValues.empty() ? NULL : &httpValues[0], - getKeys.size(), - getKeys.empty() ? NULL : &getKeys[0], - getValues.empty() ? NULL : &getValues[0]); - - if (allowed == 0) - { - return false; - } - else if (allowed != 1) + boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_); + + // Improved callback with support for GET arguments, since Orthanc 1.3.0 + for (PImpl::IncomingHttpRequestFilters2::const_iterator + filter = pimpl_->incomingHttpRequestFilters2_.begin(); + filter != pimpl_->incomingHttpRequestFilters2_.end(); ++filter) { - // The callback is only allowed to answer 0 or 1 - throw OrthancException(ErrorCode_Plugin); + int32_t allowed = (*filter) (cMethod, uri, ip, + httpKeys.size(), + httpKeys.empty() ? NULL : &httpKeys[0], + httpValues.empty() ? NULL : &httpValues[0], + getKeys.size(), + getKeys.empty() ? NULL : &getKeys[0], + getValues.empty() ? NULL : &getValues[0]); + + if (allowed == 0) + { + return false; + } + else if (allowed != 1) + { + // The callback is only allowed to answer 0 or 1 + throw OrthancException(ErrorCode_Plugin); + } } - } - - for (PImpl::IncomingHttpRequestFilters::const_iterator - filter = pimpl_->incomingHttpRequestFilters_.begin(); - filter != pimpl_->incomingHttpRequestFilters_.end(); ++filter) - { - int32_t allowed = (*filter) (cMethod, uri, ip, httpKeys.size(), - httpKeys.empty() ? NULL : &httpKeys[0], - httpValues.empty() ? NULL : &httpValues[0]); - - if (allowed == 0) + + for (PImpl::IncomingHttpRequestFilters::const_iterator + filter = pimpl_->incomingHttpRequestFilters_.begin(); + filter != pimpl_->incomingHttpRequestFilters_.end(); ++filter) { - return false; - } - else if (allowed != 1) - { - // The callback is only allowed to answer 0 or 1 - throw OrthancException(ErrorCode_Plugin); + int32_t allowed = (*filter) (cMethod, uri, ip, httpKeys.size(), + httpKeys.empty() ? NULL : &httpKeys[0], + httpValues.empty() ? NULL : &httpValues[0]); + + if (allowed == 0) + { + return false; + } + else if (allowed != 1) + { + // The callback is only allowed to answer 0 or 1 + throw OrthancException(ErrorCode_Plugin); + } } } diff -r 67e765d51bdf -r 1491d501836a Plugins/Engine/OrthancPlugins.h --- a/Plugins/Engine/OrthancPlugins.h Thu Apr 16 18:46:11 2020 +0200 +++ b/Plugins/Engine/OrthancPlugins.h Fri Apr 17 16:21:50 2020 +0200 @@ -124,6 +124,8 @@ void RegisterIncomingHttpRequestFilter2(const void* parameters); + void RegisterIncomingDicomInstanceFilter(const void* parameters); + void RegisterRefreshMetricsCallback(const void* parameters); void RegisterStorageCommitmentScpCallback(const void* parameters); @@ -252,10 +254,7 @@ const Json::Value& simplifiedTags) ORTHANC_OVERRIDE; virtual bool FilterIncomingInstance(const DicomInstanceToStore& instance, - const Json::Value& simplified) ORTHANC_OVERRIDE - { - return true; // TODO Enable filtering of instances from plugins - } + const Json::Value& simplified) ORTHANC_OVERRIDE; bool HasStorageArea() const; diff -r 67e765d51bdf -r 1491d501836a Plugins/Include/orthanc/OrthancCPlugin.h --- a/Plugins/Include/orthanc/OrthancCPlugin.h Thu Apr 16 18:46:11 2020 +0200 +++ b/Plugins/Include/orthanc/OrthancCPlugin.h Fri Apr 17 16:21:50 2020 +0200 @@ -1108,11 +1108,11 @@ /** - * @brief Signature of a callback function that is triggered when Orthanc receives a DICOM instance. + * @brief Signature of a callback function that is triggered when Orthanc stores a new DICOM instance. * @ingroup Callbacks **/ typedef OrthancPluginErrorCode (*OrthancPluginOnStoredInstanceCallback) ( - OrthancPluginDicomInstance* instance, + const OrthancPluginDicomInstance* instance, const char* instanceId); @@ -2697,12 +2697,12 @@ typedef struct { - char** resultStringToFree; - const char** resultString; - int64_t* resultInt64; - const char* key; - OrthancPluginDicomInstance* instance; - OrthancPluginInstanceOrigin* resultOrigin; /* New in Orthanc 0.9.5 SDK */ + char** resultStringToFree; + const char** resultString; + int64_t* resultInt64; + const char* key; + const OrthancPluginDicomInstance* instance; + OrthancPluginInstanceOrigin* resultOrigin; /* New in Orthanc 0.9.5 SDK */ } _OrthancPluginAccessDicomInstance; @@ -2718,8 +2718,8 @@ * @ingroup Callbacks **/ ORTHANC_PLUGIN_INLINE const char* OrthancPluginGetInstanceRemoteAet( - OrthancPluginContext* context, - OrthancPluginDicomInstance* instance) + OrthancPluginContext* context, + const OrthancPluginDicomInstance* instance) { const char* result; @@ -2751,8 +2751,8 @@ * @ingroup Callbacks **/ ORTHANC_PLUGIN_INLINE int64_t OrthancPluginGetInstanceSize( - OrthancPluginContext* context, - OrthancPluginDicomInstance* instance) + OrthancPluginContext* context, + const OrthancPluginDicomInstance* instance) { int64_t size; @@ -2784,8 +2784,8 @@ * @ingroup Callbacks **/ ORTHANC_PLUGIN_INLINE const void* OrthancPluginGetInstanceData( - OrthancPluginContext* context, - OrthancPluginDicomInstance* instance) + OrthancPluginContext* context, + const OrthancPluginDicomInstance* instance) { const char* result; @@ -2820,8 +2820,8 @@ * @ingroup Callbacks **/ ORTHANC_PLUGIN_INLINE char* OrthancPluginGetInstanceJson( - OrthancPluginContext* context, - OrthancPluginDicomInstance* instance) + OrthancPluginContext* context, + const OrthancPluginDicomInstance* instance) { char* result; @@ -2858,8 +2858,8 @@ * @ingroup Callbacks **/ ORTHANC_PLUGIN_INLINE char* OrthancPluginGetInstanceSimplifiedJson( - OrthancPluginContext* context, - OrthancPluginDicomInstance* instance) + OrthancPluginContext* context, + const OrthancPluginDicomInstance* instance) { char* result; @@ -2897,9 +2897,9 @@ * @ingroup Callbacks **/ ORTHANC_PLUGIN_INLINE int OrthancPluginHasInstanceMetadata( - OrthancPluginContext* context, - OrthancPluginDicomInstance* instance, - const char* metadata) + OrthancPluginContext* context, + const OrthancPluginDicomInstance* instance, + const char* metadata) { int64_t result; @@ -2938,9 +2938,9 @@ * @ingroup Callbacks **/ ORTHANC_PLUGIN_INLINE const char* OrthancPluginGetInstanceMetadata( - OrthancPluginContext* context, - OrthancPluginDicomInstance* instance, - const char* metadata) + OrthancPluginContext* context, + const OrthancPluginDicomInstance* instance, + const char* metadata) { const char* result; @@ -5110,8 +5110,8 @@ * @ingroup Callbacks **/ ORTHANC_PLUGIN_INLINE OrthancPluginInstanceOrigin OrthancPluginGetInstanceOrigin( - OrthancPluginContext* context, - OrthancPluginDicomInstance* instance) + OrthancPluginContext* context, + const OrthancPluginDicomInstance* instance) { OrthancPluginInstanceOrigin origin; @@ -7434,7 +7434,7 @@ * @ingroup Callback **/ typedef int32_t (*OrthancPluginIncomingDicomInstanceFilter) ( - OrthancPluginDicomInstance* instance); + const OrthancPluginDicomInstance* instance); typedef struct @@ -7478,15 +7478,15 @@ * transfer syntax UID. This string must be freed by OrthancPluginFreeString(). * @ingroup Callbacks **/ - ORTHANC_PLUGIN_INLINE const char* OrthancPluginGetInstanceTransferSyntaxUid( - OrthancPluginContext* context, - OrthancPluginDicomInstance* instance) - { - const char* result; + ORTHANC_PLUGIN_INLINE char* OrthancPluginGetInstanceTransferSyntaxUid( + OrthancPluginContext* context, + const OrthancPluginDicomInstance* instance) + { + char* result; _OrthancPluginAccessDicomInstance params; memset(¶ms, 0, sizeof(params)); - params.resultString = &result; + params.resultStringToFree = &result; params.instance = instance; if (context->InvokeService(context, _OrthancPluginService_GetInstanceTransferSyntaxUid, ¶ms) != OrthancPluginErrorCode_Success) @@ -7514,8 +7514,8 @@ * @ingroup Callbacks **/ ORTHANC_PLUGIN_INLINE int32_t OrthancPluginHasInstancePixelData( - OrthancPluginContext* context, - OrthancPluginDicomInstance* instance) + OrthancPluginContext* context, + const OrthancPluginDicomInstance* instance) { int64_t hasPixelData; diff -r 67e765d51bdf -r 1491d501836a Plugins/Samples/Basic/Plugin.c --- a/Plugins/Samples/Basic/Plugin.c Thu Apr 16 18:46:11 2020 +0200 +++ b/Plugins/Samples/Basic/Plugin.c Fri Apr 17 16:21:50 2020 +0200 @@ -29,9 +29,9 @@ static OrthancPluginErrorCode customError; -ORTHANC_PLUGINS_API OrthancPluginErrorCode Callback1(OrthancPluginRestOutput* output, - const char* url, - const OrthancPluginHttpRequest* request) +OrthancPluginErrorCode Callback1(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) { char buffer[1024]; uint32_t i; @@ -83,9 +83,9 @@ } -ORTHANC_PLUGINS_API OrthancPluginErrorCode Callback2(OrthancPluginRestOutput* output, - const char* url, - const OrthancPluginHttpRequest* request) +OrthancPluginErrorCode Callback2(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) { /* Answer with a sample 16bpp image. */ @@ -115,9 +115,9 @@ } -ORTHANC_PLUGINS_API OrthancPluginErrorCode Callback3(OrthancPluginRestOutput* output, - const char* url, - const OrthancPluginHttpRequest* request) +OrthancPluginErrorCode Callback3(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) { if (request->method != OrthancPluginHttpMethod_Get) { @@ -140,9 +140,9 @@ } -ORTHANC_PLUGINS_API OrthancPluginErrorCode Callback4(OrthancPluginRestOutput* output, - const char* url, - const OrthancPluginHttpRequest* request) +OrthancPluginErrorCode Callback4(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) { /* Answer with a sample 8bpp image. */ @@ -172,9 +172,9 @@ } -ORTHANC_PLUGINS_API OrthancPluginErrorCode Callback5(OrthancPluginRestOutput* output, - const char* url, - const OrthancPluginHttpRequest* request) +OrthancPluginErrorCode Callback5(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) { /** * Demonstration the difference between the @@ -222,9 +222,9 @@ } -ORTHANC_PLUGINS_API OrthancPluginErrorCode CallbackCreateDicom(OrthancPluginRestOutput* output, - const char* url, - const OrthancPluginHttpRequest* request) +OrthancPluginErrorCode CallbackCreateDicom(OrthancPluginRestOutput* output, + const char* url, + const OrthancPluginHttpRequest* request) { const char* pathLocator = "\"Path\" : \""; char info[1024]; @@ -266,7 +266,7 @@ } -ORTHANC_PLUGINS_API void DicomWebBinaryCallback( +void DicomWebBinaryCallback( OrthancPluginDicomWebNode* node, OrthancPluginDicomWebSetBinaryNode setter, uint32_t levelDepth, @@ -281,8 +281,8 @@ } -ORTHANC_PLUGINS_API OrthancPluginErrorCode OnStoredCallback(OrthancPluginDicomInstance* instance, - const char* instanceId) +OrthancPluginErrorCode OnStoredCallback(const OrthancPluginDicomInstance* instance, + const char* instanceId) { char buffer[256]; FILE* fp; @@ -333,9 +333,9 @@ } -ORTHANC_PLUGINS_API OrthancPluginErrorCode OnChangeCallback(OrthancPluginChangeType changeType, - OrthancPluginResourceType resourceType, - const char* resourceId) +OrthancPluginErrorCode OnChangeCallback(OrthancPluginChangeType changeType, + OrthancPluginResourceType resourceType, + const char* resourceId) { char info[1024]; @@ -391,12 +391,12 @@ } -ORTHANC_PLUGINS_API int32_t FilterIncomingHttpRequest(OrthancPluginHttpMethod method, - const char* uri, - const char* ip, - uint32_t headersCount, - const char* const* headersKeys, - const char* const* headersValues) +int32_t FilterIncomingHttpRequest(OrthancPluginHttpMethod method, + const char* uri, + const char* ip, + uint32_t headersCount, + const char* const* headersKeys, + const char* const* headersValues) { uint32_t i; @@ -423,11 +423,31 @@ } -ORTHANC_PLUGINS_API void RefreshMetrics() +static void RefreshMetrics() { static unsigned int count = 0; OrthancPluginSetMetricsValue(context, "sample_counter", - (float) (count++), OrthancPluginMetricsType_Default); + (float) (count++), OrthancPluginMetricsType_Default); +} + + +static int32_t FilterIncomingDicomInstance(const OrthancPluginDicomInstance* instance) +{ + char buf[1024]; + char* s; + int32_t hasPixelData; + + s = OrthancPluginGetInstanceTransferSyntaxUid(context, instance); + sprintf(buf, "Incoming transfer syntax: %s", s); + OrthancPluginFreeString(context, s); + OrthancPluginLogWarning(context, buf); + + hasPixelData = OrthancPluginHasInstancePixelData(context, instance); + sprintf(buf, "Incoming has pixel data: %d", hasPixelData); + OrthancPluginLogWarning(context, buf); + + // Reject all instances without pixel data + return hasPixelData; } @@ -495,7 +515,8 @@ OrthancPluginRegisterOnChangeCallback(context, OnChangeCallback); OrthancPluginRegisterIncomingHttpRequestFilter(context, FilterIncomingHttpRequest); OrthancPluginRegisterRefreshMetricsCallback(context, RefreshMetrics); - + OrthancPluginRegisterIncomingDicomInstanceFilter(context, FilterIncomingDicomInstance); + /* Declare several properties of the plugin */ OrthancPluginSetRootUri(context, "/plugin/hello");